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

时间:2009-05-04 23:18:20

标签: .net c++-cli clr

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

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

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

MYCO int WINAPI MyCo_Device_Register_CallbackFunc(LPVOID func, LPVOID lpParam, DWORD mask);

这是供应商定义的回调:

typedef void (CALLBACK* MyCo_Device_CallbackProc)(DWORD ddStatus, LPVOID lpParam);

我的回调函数:

public ref class Device 
{
    void CallBackFunc(DWORD ddStatus, LPVOID lpParam) {};
}

我的电话(失败):

MyCo_Device_Register_CallbackFunc((LPVOID) Device::CallBackFunc, nullptr, 0xFFFF);

2 个答案:

答案 0 :(得分:9)

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

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

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

public delegate void CallbackFuncDelegate(DWORD ddStatus, LPVOID lpParam);

然后,你需要创建一个:

CallbackFuncDelegate del = gcnew CallbackFuncDelegate(CallbackFunc);

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

MyCo_Device_Register_CallbackFunc((MyCo_Device_CallbackProc) Marshal::GetFunctionPointerForDelegate(del).ToPointer(), 0, 0);

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

答案 1 :(得分:0)

你的回调函数是一个成员 - 指向成员的指针和指向函数的指针是不同的东西。

即使在Promit的解决方案中:

CallbackFuncDelegate(CallbackFunc)

CallbackFunc不应该是类成员

你可以写简单

public ref class Device 
{
    static void CallBackFunc(DWORD ddStatus, LPVOID lpParam) {};
}

然后使用

Device::CallBackFunc