Alright I figured out some of the main issues! It came down to this sentence that I read about mixing C and C++ that I found online, “if you are stuck with a C-style callback, there is no direct way to call a member function” So, I had to create a reference to the UObject I was working with (ACabiListener) in the header file and then declare it at begin play in the .cpp. Here’s the code that worked:
Header file (CabiListener.h):
UCLASS()
class CABI_API ACabiListener : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ACabiListener();
static ACabiListener* Listener;
static void callback(UINT cb_type, UINT cb_src, UINT cb_srcbit, UINT cb_data, void* context);
UFUNCTION(BlueprintImplementableEvent)
void PlayButtonPressed();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};
CPP file (CabiListener.cpp)
#include "CabiListener.h"
#include "Engine/Engine.h"
ACabiListener* ACabiListener::Listener;
void ACabiListener::callback(UINT cb_type, UINT cb_src, UINT cb_srcbit, UINT cb_data, void* context)
{
Listener->PlayButtonPressed();
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Emerald, FString::Printf(TEXT("A Button was pressed!")));
}
void ACabiListener::BeginPlay()
{
Super::BeginPlay();
Listener = this;
libsetting.int_callback_fun = (int_callback_fun_t)callback;
}
I’m calling it within a child Blueprint of ACabiListener like so:
Now I can compile and play, but when I package the game and run the play function, it crashes with an Assertion error that looks like this:
Assertion failed: FPlatformTLS::GetCurrentThreadId() == GGameThreadId [File:D:/Build/++UE4/Sync/Engine/Source/Runtime/Engine/Private/AudioThread.cpp] [Line: 291]
OTDemo1!FDebug::AssertFailed()
OTDemo1!FDebug::CheckVerifyFailedImpl()
OTDemo1!FAudioThread::RunCommandOnAudioThread()
OTDemo1!FAudioDevice::AddNewActiveSoundInternal()
OTDemo1!UGameplayStatics::PlaySound2D()
OTDemo1!UGameplayStatics::execPlaySound2D()
OTDemo1!UFunction::Invoke()
OTDemo1!UObject::CallFunction()
OTDemo1!UObject::ProcessContextOpcode()
OTDemo1!ProcessLocalScriptFunction()
OTDemo1!ProcessScriptFunction<void (__cdecl*)(UObject * __ptr64,FFrame & __ptr64,void * __ptr64)>()
OTDemo1!ProcessLocalFunction()
OTDemo1!ProcessLocalScriptFunction()
OTDemo1!ProcessScriptFunction<void (__cdecl*)(UObject * __ptr64,FFrame & __ptr64,void * __ptr64)>()
OTDemo1!ProcessLocalFunction()
OTDemo1!UObject::ProcessContextOpcode()
OTDemo1!ProcessLocalScriptFunction()
OTDemo1!ProcessScriptFunction<void (__cdecl*)(UObject * __ptr64,FFrame & __ptr64,void * __ptr64)>()
OTDemo1!ProcessLocalFunction()
OTDemo1!ProcessLocalScriptFunction()
OTDemo1!UObject::ProcessInternal()
OTDemo1!UFunction::Invoke()
OTDemo1!UObject::ProcessEvent()
OTDemo1!AActor::ProcessEvent()
OTDemo1!ACabiListener::callback() [F:\GameDevelopment\ProjectOhioTakover\Game Projects\OTDemo1\Plugins\Cabi\Source\Cabi\Private\CabiListener.cpp:31]
GPCLIB
kernel32
ntdll
I’m soooo close to getting this to work completely. Am I missing something with the reference? Any ideas on what’s causing the Assertion error? Thanks for the replies thus far guys, I really appreciate your help.
Not sure if this has to do with anything, but it’s throwing this warning on build as well:
winnt.h(620): [C4005] 'TEXT': macro redefinition
Platform.h(1085): [C4005] see previous definition of 'TEXT'
This started happening after I renamed a cpp file a while ago. Since then, I’ve deleted it and completely restarted, but it’s still throwing the warning. When I double click the warning it takes me to the winnt.h file and shows me a #define that looks like this:
#define TEXT(quote) __TEXT(quote) // r_winnt
Pretty sure I’m redefining the TEXT macro somewhere but I don’t know how or where to find it…