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

时间:2014-04-07 08:37:38

标签: c# c++ .net dll pinvoke

我是c ++ DLL实现示例,我想在C#中使用Interop构建GUI和Web服务。

这是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#对C ++ DLL进行的其他外部调用工作正常,但在此调用中我必须传递" EventInterfaceEx "而且我不知道该怎么做。 可以翻译" CDivaEventNotify"和" CDivaEventNotifyEx"实现到c#并将其传递给extern dll Interop DIVA_Mgmt_RegisterEventInterfaceEx?

1 个答案:

答案 0 :(得分:1)

无法在C#中实施CDivaEventNotifyCDivaEventNotifyEx。如果这些是COM兼容的接口,那么它们可以实现。但他们不是。

坦率地说,这个API根本不容易打电话。它并没有真正考虑到互操作性。它依赖于接口的实现者以与本机代码相同的方式布置vtable。

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