将 DLL c++ 事件注册到 C#

本文关键字:注册 事件 DLL c++ | 更新日期: 2023-09-27 17:57:00

我有 c++ DLL 实现示例,我想用 C# 构建一个 GUI 和 Web 服务,使用 Interop。

这是C++实现的示例:

//DLL headers (only what we need)
extern  DWORD   __stdcall   DIVA_Mgmt_RegisterEventInterfaceEx ( HANDLE hInstance, HANDLE hAdapter, DWORD dwEventMask, 
                                                                   void *pEventInterfaceEx );
//code of exe sample
class   CDivaEventNotify
{
public:
//    virtual ~CDivaEventNotify () {}   see comment at CDivaCardStatistics
    virtual void    StateLayer1Changed ( DWORD dwNewState ) = 0;
    virtual void    StateLayer2Changed ( DWORD dwNewState ) = 0;
    virtual void    CallsChanged ( BOOL bInbound ) = 0;
    virtual void    LineStateChanged ( DWORD dwChannel, BOOL bUp, B_CHANNEL_INFO *pChannelInfo ) = 0;
};
/*
 * extended event interface for analog card support
 */
class   CDivaEventNotifyEx : public CDivaEventNotify
{
public:
//    virtual ~CDivaEventNotifyEx () {}   see comment at CDivaCardStatistics
    virtual void    PotsLineStateChanged ( DWORD dwNewState, DWORD dwLine ) = 0;
    virtual void    AlarmChanged ( PRI_ALARM alarm, BOOL bNewState ) = 0;
};
class CMyEventHandler : public CDivaEventNotifyEx
{
 //omit implementation...
}
int main(){
    HANDLE hInstance;
    CMyEventHandler *pHandlerList = NULL;
    static const DWORD dwEvMask = DIVA_EVENT_MASK_ALL;
    DIVA_Mgmt_RegisterInstance( DIVA_MGMT_IF_VERSION, &hInstance );

    while (DIVA_Mgmt_EnumAdapter( hInstance, &hEnum, &info ) == IDI_SUCCESS)
    {
        CMyEventHandler *pNew = new CMyEventHandler( hInstance, &info );
        if (!pNew)
            continue;
        DIVA_Mgmt_RegisterEventInterfaceEx( hInstance, info.hAdapter, dwEvMask, pNew );
        pNew->pNext = pHandlerList;
        pHandlerList = pNew;
    }
}

此代码在 c++ 环境中工作正常。这个DLL不符合COM标准,我在c#中用Interop P/Invoke调用它。

[DllImport("dimgmtif.dll", SetLastError = true)]
public static extern IntPtr DIVA_Mgmt_RegisterEventInterfaceEx(IntPtr hInstance, IntPtr hAdapter, UInt32 dwEventMask,ref IntPtrp EventInterfaceEx);

使用 C# 对 DLL 的其他外部调用C++工作正常,但在此调用中我必须传递"EventInterfaceEx",我不知道该怎么做。是否可以将"CDivaEventNotify"和"CDivaEventNotifyEx"实现转换为c#并将其传递给extern dll Interop DIVA_Mgmt_RegisterEventInterfaceEx?

将 DLL c++ 事件注册到 C#

不可能

在 C# 中实现CDivaEventNotifyCDivaEventNotifyEx。如果这些是COM兼容接口,则可以实现它们。但事实并非如此。

坦率地说,这个 API 根本不容易调用。它在设计时并没有真正考虑到互操作。它依赖于接口的实现器以与本机代码相同的方式布置 vtable。

解决此问题

的最大希望在于以混合模式 C++/CLI 程序集实现接口。可以在此处包装功能,并将其公开为 C# 代码使用的 ref 类。