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

标签 c# c++ .net dll pinvoke

我有 C++ DLL 实现示例,我想使用 Interop 在 C# 中构建 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?

最佳答案

不可能在 C# 中实现 CDivaEventNotifyCDivaEventNotifyEx。如果这些是 COM 兼容接口(interface),那么它们就可以实现。但他们不是。

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

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

关于c# - 将 DLL c++ 事件注册到 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22907392/

相关文章:

c# - 提供给 .NET 通用构造函数的类型参数,但仍然会导致错误,就好像没有

c# - 使用 HttpClient 时出现 HttpRequestException?

c# - c# 和 php 中的哈希值不相同

c++ - 具有多个键/值的无序容器

c# - 如何运行具有不同配置文件的可执行程序?

c# - 为什么在具有两个进程和输出重定向的代码中没有捕获到 ThreadAbortException?

C# - MySQL 阻止 TINYINT(1) 到 bool 值的转换

python - 使用 PyObject_CallMethod 调用带有可选参数的函数

c++ - 将 boost::bind 与包含 boost::mutex 的类一起使用

c# - Exchange Web 服务 - 获取附件始终为空