将 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?
不可能
在 C# 中实现CDivaEventNotify
或CDivaEventNotifyEx
。如果这些是COM兼容接口,则可以实现它们。但事实并非如此。
坦率地说,这个 API 根本不容易调用。它在设计时并没有真正考虑到互操作。它依赖于接口的实现器以与本机代码相同的方式布置 vtable。
解决此问题的最大希望在于以混合模式 C++/CLI 程序集实现接口。可以在此处包装功能,并将其公开为 C# 代码使用的 ref 类。