背景
现在在写一个给C#用的dll,该dll是由C++编写的,该dll里会有些事件例如OnInitialized会被执行,现在想接受到这些事件通知时,调用C#的函数,但是又不能使用CLI,在思考有什么实现思路吗
解决思路
使用C++ DLL中的回调(Callback)
简单解释
C++ DLL中可以定义一些回调函数,当DLL中的某些事件发生时,就调用这些函数。在C#代码中,你可以创建一些函数用于接收这些回调,并且这些函数需要使用 [MarshalAs] 属性修饰,并指定 CallingConvention 为 Cdecl 或者 StdCall。这种方式的话,C#和C++的代码就需要更紧密的配合。
详细解释
在这个例子中,我将为你展示如何从C++ DLL引发回调,然后在C#中处理它。
首先,你的C++ DLL需要包含一个能被外部调用的函数,用来注册C#的回调函数。我们这里假设你有一个函数叫OnInitialize
, 我们需要在该函数触发时也触发C#中的回调函数。
假设你的 C++ DLL 代码如下:
// 你的C++ DLL
#include <functional>
// 回调函数类型
typedef void (__stdcall *CallbackType)();
// 回调函数
CallbackType _callback = nullptr;
// 注册回调函数
extern "C" __declspec(dllexport) void RegisterCallback(CallbackType callback) {
_callback = callback;
}
extern "C" __declspec(dllexport) void Initialize() {
// 执行一些初始化操作...
// 判断回调是否存在,并调用
if (_callback) {
_callback();
}
}
在你的 C# 程序中,你需要定义和C++ DLL中相同签名的回调函数,然后注册该回调。假设你的C#代码如下:
class Program
{
//声明回调函数的签名
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void CallbackType();
//将Dll的方法进行映射
[DllImport("YourDll.dll")]
public static extern void RegisterCallback(CallbackType callback);
[DllImport("YourDll.dll")]
public static extern void Initialize();
//定义处理函数
public static void Handler()
{
//处理从DLL传过来的通知
Console.WriteLine("Callback received from the DLL.");
}
static void Main(string[] args)
{
//注册C#回调函数到DLL
RegisterCallback(new CallbackType(Handler));
//触发初始化函数
Initialize();
}
}
在上述的C#代码中,Handler
函数是你预备处理DLL通知的函数,RegisterCallback
方法则向 DLL 注册了这个处理函数,当 DLL 中的事件发生时(即 Initialize
被调用时),处理函数就会接收到通知并做出响应。
这只是一个简单的例子,实际使用场景可能需要处理的会更复杂一些,比如需要传递的参数更多或者类型更复杂,你就需要对回调函数的签名做出相应的调整。同样,这个例子中假设了Initialize
和 RegisterCallback
都是同步调用的,如果这两个函数是异步的,那么你可能还需要处理异步调用的情况。
小结
可以通过callback的方式进行回调,不要急于上手项目改动,可编写一下DEMO进行试验一下,希望给遇到相同困扰的兄弟姐妹们提供一些参考。