我有 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# 中实现 CDivaEventNotify
或 CDivaEventNotifyEx
。如果这些是 COM 兼容接口(interface),那么它们就可以实现。但他们不是。
坦率地说,这个 API 根本不是很容易调用。它在设计时并没有真正考虑到互操作性。它依赖于接口(interface)的实现者以与 native 代码相同的方式布置 vtable。
解决此问题的最大希望在于在混合模式 C++/CLI 程序集中实现接口(interface)。您可以在那里封装功能,并将其公开为供 C# 代码使用的 ref 类。
关于c# - 将 DLL c++ 事件注册到 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22907392/