c++到c#回调结构的编组

C++ to C# Callback Struct Marshalling

本文关键字:结构 回调 c++      更新时间:2023-10-16

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

我使用c++ .dll编译(我没有机会改变它,重新编译或修改它)我有。h那里有一些(坏文档)信息。此dll用于与通过USB连接的设备进行交互。设备正确配置并使用dll提供的功能,我绝对确定它正确响应dll调用。从c++和c#进行封送是相当容易的,直到我不得不使用Callback来注册设备抛出的一些事件。

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

//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,我无法捕捉到错误)。

我可以有一个实现的例子给出上面的代码片段?

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

嗯,我不知道你做了多少封送处理,所以我假设你在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),

记住只要回调可以被调用,就保持委托实例存活(即保持对它的引用)