C#封送回调函数和委托
因需要,需要封装一个C++网络库到C#环境使用,而C++网络库是使用的事件的方式,也就是说,发生网络事件时,C++网络库发出事件通知,而真正的处理函数在C#端。这就要求,在封装时需要封装一个函数指针以实现回调。下面代码实现了如上功能。
上网找了一下,找到的一般都是封送值,结构,一般函数的,所以就想写出来分享一下。
关键词:C# C++ 互操作 封送 封送回调函数 封送函数指针 C#C++回调
建两个工程
//CallBackDelegate.cs usingSystem; usingSystem.Collections.Generic; usingSystem.Text; usingSystem.Runtime.InteropServices;
namespaceCallBackInteropTest { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] publicdelegateintCallBackDelegate(intnum1,intnum2);
classCallBackClass {
[DllImport("NativeDll.dll", EntryPoint = "AddThreeNum")] privatestaticexternintAddThreeNum(IntPtrpFun, intnum1, intnum2, intnum3); //初始化
publicintTestCallBackAddThreeNum(intnum1, intnum2, intnum3) { CallBackDelegatecbd = newCallBackDelegate(CallBack_Add); //GCHandle can prohibit gc to release delegate object GCHandlegchDelegate = GCHandle.Alloc(cbd); //Marshal delegate object ,get func pointer IntPtrpFunc = Marshal.GetFunctionPointerForDelegate(cbd);
intreturnValue = AddThreeNum(pFunc, num1, num2, num3); //Free GCHandle Object,allow gc to release delegate object gchDelegate.Free(); returnreturnValue;
}
privateintCallBack_Add(intnum1, intnum2) { returnnum1 +num2; } } }
|
//Program.cs usingSystem; usingSystem.Collections.Generic; usingSystem.Text;
namespaceCallBackInteropTest { classProgram { staticvoidMain(string[] args) { CallBackClasscbc = newCallBackClass(); Console.WriteLine(cbc.TestCallBackAddThreeNum(3, 4, 5).ToString ()); } } }
|
// dllmain.cpp : 定义DLL 应用程序的入口点。 #include"stdafx.h"
typedefint (__cdecl *PCallbackFunc)(intnum1,intnum2);
extern"C"__declspec(dllexport) int AddThreeNum(PCallbackFuncpFunc,intnum1,intnum2,intnum3) { inttwoNum = (*pFunc)(num1,num2); returntwoNum+num3; }
BOOLAPIENTRYDllMain( HMODULEhModule, DWORD ul_reason_for_call, LPVOIDlpReserved ) { switch (ul_reason_for_call) { caseDLL_PROCESS_ATTACH: caseDLL_THREAD_ATTACH: caseDLL_THREAD_DETACH: caseDLL_PROCESS_DETACH: break; } returnTRUE; } |
代码下载地址:
http://download.csdn.net/detail/hbhbice/4977424
最后,忘记说了,编译器选项中,目标平台选择 x86, x64 anycpu都是不可以的。都会有异常,我不知道为什么,如果有人知道,麻烦告知一下,谢谢