C ++到C#回调结构编组

时间:2014-06-24 08:18:39

标签: c# c++ dll marshalling

我在我的项目中遇到了一些麻烦。

我正在使用c ++ .dll编译(我没有机会改变它,重新编译或修改它)我有.h,其中有一些(记录不好)信息。 此dll用于与通过USB连接的设备进行交互。该设备已正确配置,并使用dll提供的功能,我有绝对的确定,它正确回答dll调用。 从c ++和c#编组很容易,直到我必须使用Callback来注册设备抛出的某些事件。

这是c ++的重要部分。我必须在c#中使用 (第一和第二个事件是假名)

//First Event data
typedef struct tagFIRST_EVENT {
    int a; 
    int b; 
    int c;
} FIRST_EVENT;

//SecondEvent data
typedef struct tagSECOND_EVENT {
    int e; 
    int f; 
} SECOND_EVENT;

//first event callback?
typedef void (CALLBACK *FIRTS_EVENT_LISTENER)(FIRST_EVENT *event, void *userData);  

//second event callback?
typedef void (CALLBACK *SECOND_EVENT_LISTENER)(SECOND_EVENT *event, void *userData);


//Register to all given callback in the struct LISTENER
int WINAPI RegisterEvents(LISTENER *listenerGroup );

typedef struct tagLISTENER {
    FIRTS_EVENT_LISTENER first_listener;
    SECOND_EVENT_LISTENER second_listener;
    void * userData;
} LISTENER;

我在编组时遇到麻烦,让c ++ .dll调用我定义的c#函数来处理设备抛出的事件。

我已经找到了很多例子,但是我无法以正确的方式使用这些功能。基本上c#应用程序崩溃没有任何进一步的信息(我认为因为错误是在c ++ DLL中,我无法捕获错误)。

根据上面的代码片段,我可以有一个实现示例吗?

我搜索得很深,我发现只有类似的问题,但没有一个可以帮助我。 我在这里有任何澄清,谢谢你的建议!

1 个答案:

答案 0 :(得分:1)

好吧,我不知道你做了多少封送,所以我假设你在C#中为FirstEventSecondEvent数据类型创建了二进制兼容类型。

对于函数指针,您只需要IntPtr

毕竟(如果你没有创建二进制兼容类型,我会扩展),你所要做的就是创建一个本身是二进制兼容的委托:

delegate void FirstEventListener(ref FirstEvent firstEvent, IntPtr userData);
delegate void SecondEventListener(ref SecondEvent secondEvent, IntPtr userData);

然后,您可以为实际处理程序创建委托实例,并使用[Marshal.GetFunctionPointerForDelegate](http://msdn.microsoft.com/en-us/library/at4fb09f.ASPX)获取指针(IntPtr),

只要可以调用回调,就保持该委托实例保持活动状态(即保持对它的引用)。