在C / CLI中创建许多委托/回调并维护DRY

时间:2015-05-27 14:54:58

标签: c# delegates c++-cli dry

许多文章,包括here,  向我展示了如何使用C ++ / CLI委托作为C ++回调:

typedef void(*SDKUnManagedCB)(void * c, void *c2);

后...

[UnmanagedFunctionPointer(CallingConvention::Cdecl)]
delegate void sdkCBStyle(void * c, void *c2);

后...

sdkCBStyle^ users = gcnew sdkCBStyle(this, &SDK::UsersCB); //2nd parameter is method here in CLI file
IntPtr pUsers = Marshal::GetFunctionPointerForDelegate(users);
GC::KeepAlive(users);  //freed later
GetUsers(static_cast<SDKUnManagedCB>(pUsers.ToPointer())); //GetUsers is unmanaged 3rd party API

我的问题是,我有大约20个具有相同签名的回调,我想简化复杂的CLI代码。我想做这样的事情:

GetUsers(CreateCallBack(&SDK::UsersCB));
GetActions(CreateCallBack(&SDK::ActionsCB));
//etc

问题是我找不到传递该函数名的正确函数签名。 F12(转到定义)转到委托的定义 Intellisense还显示了函数签名

MSDN has two protected constructors都将String作为我尝试使用的第二个参数

Delegate(Object, String)

但是当我尝试时:

SDKUnManagedCB CBCreator(String method) {
sdkCBStyle^ piCB = gcnew sdkCBStyle(this, method); // yes my variable names suck...

实时编译显示错误工具提示:

Error: invalid delegate initializer -- must be a function

我试图调查CreateDelegate,但这看起来很慢

SDKUnManagedCB CBCreator(String^ method) {
    MethodInfo^ info = GetType()->GetMethod(method, BindingFlags::Public | BindingFlags::Instance);

    sdkCBStyle^ piCB = static_cast<sdkCBStyle^>(Delegate::CreateDelegate(sdkCBStyle::typeid, info)); 
    GC::KeepAlive(piCB);   // Yes this is a known leak, it will have to be stored as a member and explictly freed
    return  static_cast<SDKUnManagedCB>((Marshal::GetFunctionPointerForDelegate(piCB)).ToPointer());

}

跟:

GetObjects(CBCreator("ObjectCB"));

看起来它编译,但是有更简单的方法吗?

编辑:它在运行时崩溃了, mscorlib.dll中出现未处理的“System.ArgumentException”类型异常 附加信息:无法绑定到目标方法,因为其签名或安全透明度与委托类型的方法不兼容。

我需要更多的绑定参数;回调必须是数据封装的成员函数

0 个答案:

没有答案