C3374:除非创建委托实例,否则无法获取'function'的地址

Med*_*Man 4 .net clr c++-cli

我在使用第三方库注册功能注册回调时遇到困难.我在C++ CLI中编写,并访问用C或C++编写的库.

上述编译器错误是什么意思?

这是供应商定义的注册功能:

MYCO int WINAPI MyCo_Device_Register_CallbackFunc(LPVOID func, LPVOID lpParam, DWORD mask);
Run Code Online (Sandbox Code Playgroud)

这是供应商定义的回调:

typedef void (CALLBACK* MyCo_Device_CallbackProc)(DWORD ddStatus, LPVOID lpParam);
Run Code Online (Sandbox Code Playgroud)

我的回调函数:

public ref class Device 
{
    void CallBackFunc(DWORD ddStatus, LPVOID lpParam) {};
}
Run Code Online (Sandbox Code Playgroud)

我的电话(失败):

MyCo_Device_Register_CallbackFunc((LPVOID) Device::CallBackFunc, nullptr, 0xFFFF);
Run Code Online (Sandbox Code Playgroud)

Pro*_*mit 9

如果我不得不下注,你试图获取一个MANAGED函数的地址并将其作为NATIVE函数指针传递.这根本行不通.编写本机桥(更难,可能没有优势),或(这是更简单的方法),创建委托并使用Marshal.GetFunctionPointerForDelegate.不要忘记委托必须在本机代码期望回调的时间内保持活动状态,因此您很可能需要将其存储在某处.

哦,ref类或值类中的所有函数都是托管函数,如果不清楚的话.

[编辑]扩大答案以涵盖评论中的问题.第一步是创建匹配的委托.对于您提供的功能,它将如下所示:

public delegate void CallbackFuncDelegate(DWORD ddStatus, LPVOID lpParam);
Run Code Online (Sandbox Code Playgroud)

然后,你需要创建一个:

CallbackFuncDelegate del = gcnew CallbackFuncDelegate(CallbackFunc);
Run Code Online (Sandbox Code Playgroud)

如前所述,您应该将其作为成员存储在您的班级中,以确保它不会消失.最后,您需要获取函数指针并将其传递下去:

MyCo_Device_Register_CallbackFunc((MyCo_Device_CallbackProc) Marshal::GetFunctionPointerForDelegate(del).ToPointer(), 0, 0);
Run Code Online (Sandbox Code Playgroud)

我认为这涵盖了一切.您只需要使用命名空间系统; 你应该没事

  • 正如msdn上的此错误示例显示http://msdn.microsoft.com/en-us/library/5408cs95(VS.80).aspx,您可以在创建委托时传入对设备的引用:CallbackFuncDelegate ^ del = gcnew CallbackFuncDelegate(device,&Device :: CallbackFunc); 然后它不需要是静态方法. (3认同)