我用於從C#委託註冊以這樣的回調函數指針(不使用Marshal.GetFunctionPointerForDelegate):註冊C#委託給C++回調,Marshal.GetFunctionPointerForDelegate做什麼?
C++(Test.dll的)
typedef void (__stdcall* Callback)(int num);
Callback pCallback = 0;
void __stdcall SetCallback(Callback callback)
{
pCallback = callback;
}
void __stdcall ActionCpp()
{
if(pCallback)
{
pCallback();
}
}
C#
class Program
{
[DllImport("Test.dll", CallingConvention = CallingConvention.StdCall)]
public static extern void SetCallBack(Callback callback);
[DllImport("Test.dll", CallingConvention = CallingConvention.StdCall)]
public static extern void ActionCpp();
public delegate void Callback();
static void Action()
{
Console.WriteLine("Callback succeeded.");
}
static void Main(string[] args)
{
Callback myAction = new Callback(Action);
SetCallback(myAction);
ActionCpp(); //Suppose to do the same thing as Action();
}
}
看來這種方式很好。然而,我發現我們可以通過使用Marshal.GetFunctionPointerForDelegate來完成相同的事情,並將委託的IntPtr註冊到C++中的函數指針。 我想知道有什麼不同以及哪種做法更好? (也爲什麼?提前致謝。)
這是使用Marshal.GetFunctionPointerForDelegate時的C#代碼。 (沒有在C++代碼更改。)
C#(帶Marshal.GetFunctionPointerForDelegate)
class Program
{
[DllImport("Test.dll", CallingConvention = CallingConvention.StdCall)]
public static extern void SetCallBack(IntPtr pCallBack); //change to type "IntPtr" this time.
[DllImport("Test.dll", CallingConvention = CallingConvention.StdCall)]
public static extern void ActionCpp();
public delegate void Callback();
static void Action()
{
Console.WriteLine("Callback succeeded.");
}
static void Main(string[] args)
{
Callback myAction = new Callback(Action);
//GCHandle gcHandle = GCHandle.Alloc(myAction); <-- Is this necessary?
IntPtr pMyAction = Marshal.GetFunctionPointerForDelegate(myAction);
SetCallback(pMyAction);
ActionCpp();
//gcHandle.Free();
}
}
我又一但關於是否有必要使用「GCHandle.Alloc」(在我的意見相關的問題在上面的代碼中),以避免任何GC行動,只要我的回調myAction仍然活着? 我是C#和C++回調的新手,如果我有天真的錯誤,請告訴我。