Do dll callback

I try make dll callback. I make worked solution, but it use void function without my class, and i cant make some logic here. I try rework logic CatchErrorFunc to UWebClientHandler::CatchErrorFunc, and no see right way.

#include "WebClientHandler.h"
#include "WebController.h"
#include "Runtime/Core/Public/Misc/Paths.h"

void *DLLHandlerGet;
typedef void (* StringCallbackVoidF)(const char *data);
StringCallbackVoidF PtrCatchErrorFunc;
void CatchErrorFunc(const char* msg);
typedef void(*GetErrorCallbackVoidF)(StringCallbackVoidF callback);

void UWebClientHandler::Init()
{
	Super::Init();
	UE_LOG(LogTemp, Warning,TEXT("UWebClientHandler: init"));
	
	ImportDLL();
	RegCallBack();
	TestCallback();
}

bool UWebClientHandler::ImportDLL()
{
	FString folder = "WebSocketClient";
	FString fileName = "websocket-sharp.dll";	
	FString filePath = *FPaths::ProjectPluginsDir() + folder + "/" + fileName;	
	if (FPaths::FileExists(filePath))
	{
		//UE_LOG(LogTemp, Warning,TEXT("UWebClientHandler:ImportDLL: dll path exist"));
		DLLHandlerGet = FPlatformProcess::GetDllHandle(*filePath); // Retrieve the DLL.
		if (DLLHandlerGet != nullptr)
		{
			//UE_LOG(LogTemp, Warning,TEXT("UWebClientHandler:ImportDLL: dll TRUE"));
			return true;
		}
		//UE_LOG(LogTemp, Warning,TEXT("UWebClientHandler:ImportDLL: dll FALSE"));
	}
	return false;		
}

void UWebClientHandler::RegCallBack()
{
	if (DLLHandlerGet == nullptr)
	{
		UE_LOG(LogTemp, Warning,TEXT("UWebClientHandler: DLL is Null"));
		return;
	}

	const FString RegisterErrorString = "RegisterErrorCB";
	GetErrorCallbackVoidF GetCatchErrorVoid = (GetErrorCallbackVoidF)FPlatformProcess::GetDllExport(PtrCatchErrorFunc, *RegisterErrorString);
	if (GetCatchErrorVoid != nullptr)
	{	
		PtrCatchErrorFunc = &CatchErrorFunc;
		GetCatchErrorVoid(PtrCatchErrorFunc);	
		UE_LOG(LogTemp, Warning,TEXT("UWebClientHandler: PtrCatchError reg = DONE"));
	}
	
}

void UWebClientHandler::TestCallback()
{
	if (DLLHandlerGet == nullptr)
	{
		UE_LOG(LogTemp, Warning,TEXT("UWebClientHandler: DLL is Null"));
		return;
	}
	const FString ConnectString = "Connect";

	typedef void (* ActionCallbackVoidF)();
	ActionCallbackVoidF PtrConnect = (ActionCallbackVoidF)FPlatformProcess::GetDllExport(DLLHandlerGet, *ConnectString); 	
	if (PtrConnect != nullptr)
	{	
		PtrConnect();
		UE_LOG(LogTemp, Warning,TEXT("UWebClientHandler: Connect()"));
	}
}

//NOT WORKING
//void UWebClientHandler::CatchErrorFunc(const char* msg){ UE_LOG(LogTemp, Warning,TEXT("UWebClientHandler. EVENT ERROR:  %hs"),msg); }

//WORK FINE
void CatchErrorFunc(const char* msg){ UE_LOG(LogTemp, Warning,TEXT("UWebClientHandler. EVENT ERROR:  %hs"),msg); }

I rewok it to static void. It work too, but it static and i still cant do some logic here.

//NOT WORKING
//void UWebClientHandler::CatchErrorFunc(const char* msg){UE_LOG(LogTemp, Warning,TEXT("UWebClientHandler. EVENT ERROR:  %hs"),msg);}

//WORK FINE
void CatchErrorFunc(const char* msg)
{
	UWebClientHandler::DoSomething(msg);
	UE_LOG(LogTemp, Warning,TEXT("UWebClientHandler. EVENT ERROR:  %hs"),msg);
}

void UWebClientHandler::DoSomething(const char* msg)
{
	
}

Ehh… Fail…
i try use here events functions

	UFUNCTION(BlueprintImplementableEvent, Category = "Websocket")
	void OnErrorEvent(const FString& SampleValue);

This not static, and i still no have solution.

I think i need static link on self, after this i can use
UWebClientHandler::WebClientHandler->DoSomething(msg);

Store a reference to your object in a global weak object pointer, and use a global function or a non-capturing lambda to route the callback back into the object :

TWeakObjectPtr<UWebClientHandler> GlobalPtr = nullptr;

void UWebClientHandler::Init()
{
    GlobalPtr = this;
}

void UWebClientHandler::RegCallBack()
{
    PtrCatchErrorFunc = &GlobalCatchError;
}

void GlobalCatchError(const char* msg)
{
    if (GlobalPtr.IsValid())
        GlobalPtr->CatchError(msg);
}

void UWebClientHandler::CatchError(const char* msg)
{
    //...
}

Obviously this only works properly if you have only one UWebClientHandler object.
If you have multiple simultaneously, you’ll have to somehow associate each callback with each instance. This might not be possible if the API doesn’t provide more specific callbacks (like for example with some extra parameters to discriminate).
If you plan to have a finite amount, you could resort to adding as many weak pointers and associated global callbacks as needed, and round-robin between them.

1 Like

Thanks. Its give me much more ideas.