2016-08-12 5 views
0

Robert GieseckeのUnmanaged Exportsを使用して、ネイティブC++アプリケーションからC#managed dllの関数を呼び出しています。私は今、どういうわけか、私のDLLがC++にコールバックをすることができるように、私のC++アプリケーションから関数ポインタをC#dllに渡す必要があります。これは私に困ってしまった。C++からC#dllへの関数ポインタをコールバックとして使用するためのコールバック

C++

//Normal call to CSharp dll using Unmanaged Exports 
FString UHostBridgeComponent::DoCallToCCsharp() 
{ 

    FString filePath = FPaths::Combine(*FPaths::GamePluginsDir(), TEXT("ThirdParty"), TEXT("CSharp.dll")); 

    void *DLLHandle = NULL; 
    if (FPaths::FileExists(filePath)) 
    { 
    DLLHandle = FPlatformProcess::GetDllHandle(*filePath); // Retrieve the DLL. 
    } 
    if (DLLHandle != NULL) 
    { 
    _DoTest DLLFuncPtr = NULL; 
    FString procName = "DoTest"; 
    DLLFuncPtr = (_DoTest)FPlatformProcess::GetDllExport(DLLHandle, *procName); 
    if (DLLFuncPtr != NULL) 
    { 
     const char* result = DLLFuncPtr(false); 
     FString output(result); 
     return output; 
    } 
    } 
    return ""; 
} 

C#

//Function called from C++ application 
    [DllExport("DoTest", CallingConvention = CallingConvention.StdCall)] 
    public static string DoTest(bool result) 
    { 

     //Do processing 
     //... 

     string result = "this is the result string"; 
     return result; 
    } 

私はC#で関数を呼び出すときにC++で関数へのポインタを渡す必要があることを想像。ポインタはC#で変数に保存され、C#のDLLはC++アプリケーションにデータを送信したいときにコールバックとして実行する必要があります

const char * result = DLLFuncPtr(pointerToMyFunction); 

これらの関数と変数の定義方法がわかりません。どんな助けもありがとう。

答えて

0

私はそれを自分で理解することができました。答えは下記参照

C++

//Function pointer typedef 
typedef bool(*functionPointer)(const char* data); 

//the actual function that gets pointed to 
bool UHostBridgeComponent::realFunction(const char * data) 
{ 
    FString output(data); 
    UE_LOG(LogEGM, Log, TEXT("CALLBACK FUNCTION data= %s"), *output); 
    return true; 
} 

//function pointer as variable (not yet pointing to realFunction) 
functionPointer myFunc; 

//function to call in C# that passes the function pointer 
typedef bool(*_DoSendCallbackFunction)(functionPointer callback); 

bool UHostBridgeComponent::DoCallbackTest() 
{ 
    FString filePath = FPaths::Combine(*FPaths::GamePluginsDir(), TEXT("ThirdParty"), TEXT("CSharp.dll")); 

    void *DLLHandle = NULL; 
    if (FPaths::FileExists(filePath)) 
    { 
     DLLHandle = FPlatformProcess::GetDllHandle(*filePath); 
    } 
    if (DLLHandle != NULL) 
    {  
     _DoSendCallbackFunction DLLFuncPtr = NULL; 
     FString procName = "DoSendCallbackFunction"; 
     DLLFuncPtr = (_DoSendCallbackFunction)FPlatformProcess::GetDllExport(DLLHandle, *procName); 
     if (DLLFuncPtr != NULL) 
     { 
      myFunc = &realFunction; //point myFunc to the function realFunction 
      return DLLFuncPtr(myFunc);    
     } 
    } 
    return false; 
} 

C#の

public delegate bool FooDelegate(string data); 

    [DllExport("DoSendCallbackFunction", CallingConvention = CallingConvention.StdCall)] 
    public static bool DoSendCallbackFunction(IntPtr callback) 
    { 
     FooDelegate myFooDelegate = (FooDelegate)Marshal.GetDelegateForFunctionPointer(callback,typeof(FooDelegate)); 
     string theString = "This is the data!!"; 
     myFooDelegate(theString); 

     return true; 
    } 

、結果は私のログファイルに出力されます

LogEGM: CALLBACK FUNCTION data= This is the data!! 
関連する問題