C#调用原生C++ COM对象(在C++中实现C#的接口)
2016-12-13 15:02
399 查看
为了跨平台在.net core中使用COM,不能使用Windows下的COM注册机制,但是可以直接把IUnknown指针传给C#,转换为指针,再转换为C#的接口(interface)。
做了这方面的研究,但最终我没有使用这套技术,因为对IDispatch::Invoke的分发太麻烦了,又不能借助ATL与VS开发环境的IDL能力。所以没有继续研究事件订阅(C#是event,C++COM是IConnectionPoint)。
C++中需要做的:
简单点,实现IDispatch就可以了,全面一点,实现IManagedObject或IProvideClassInfo,后者可是个大工程。
如果我们要实现C#中定义的接口,那么最好给(不给也可以,编译器会给每个接口一个默认的GUID)接口一个GUID,.net到你的对象QueryInterface时要处理这个IID,把IDispatch指针与S_OK返回即可。
如果跨平台,把__uuidof换成实际的UUID即可。
再导出一个DLL的函数把指针给.net运行时
C#代码:
I love COM
COM思想很重要,COM最近不但活跃在Windows平台,更是蔓延到了Linux,安卓,iOS等平台。架构师,程序员应合理利用。
做了这方面的研究,但最终我没有使用这套技术,因为对IDispatch::Invoke的分发太麻烦了,又不能借助ATL与VS开发环境的IDL能力。所以没有继续研究事件订阅(C#是event,C++COM是IConnectionPoint)。
C++中需要做的:
简单点,实现IDispatch就可以了,全面一点,实现IManagedObject或IProvideClassInfo,后者可是个大工程。
如果我们要实现C#中定义的接口,那么最好给(不给也可以,编译器会给每个接口一个默认的GUID)接口一个GUID,.net到你的对象QueryInterface时要处理这个IID,把IDispatch指针与S_OK返回即可。
如果跨平台,把__uuidof换成实际的UUID即可。
struct foo : public IDispatch { // 通过 IDispatch 继承 virtual ULONG AddRef(void) override{return 0;} virtual ULONG Release(void) override{return 0;} virtual HRESULT QueryInterface(REFIID riid, void ** ppvObject) override { if (riid == __uuidof(IUnknown)) { *ppvObject = (IUnknown*)this; return S_OK; } IID uid; IIDFromString(L"{C#声明接口的GUID/IID}", &uid); if (riid == uid) { *ppvObject = (IDispatch*)this;// (IUnknown*)this; return S_OK; } if (riid == __uuidof(IDispatch)) { *ppvObject = (IDispatch*)this; return S_OK; } return E_NOTIMPL; } virtual HRESULT GetTypeInfoCount(UINT * pctinfo) override{return S_OK;} virtual HRESULT GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo ** ppTInfo) override{return S_OK;} virtual HRESULT GetIDsOfNames(REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId) override { *rgDispId = 1; return S_OK; } virtual HRESULT Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult, EXCEPINFO * pExcepInfo, UINT * puArgErr) override { cout << "be called" << endl; return S_OK; } };
再导出一个DLL的函数把指针给.net运行时
extern "C" __declspec(dllexport) foo* WINAPI GetTestObject() { return new foo;// 简单粗暴leak :) }
C#代码:
[DllImport(@"foo.dll")] static extern IntPtr GetTestObject(); [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] [Guid("your uiid")] interface Test { int func(); } var v = GetTestObject(); obj = (Test)Marshal.GetObjectForIUnknown(v); var value = obj.func();// 输出be called
I love COM
COM思想很重要,COM最近不但活跃在Windows平台,更是蔓延到了Linux,安卓,iOS等平台。架构师,程序员应合理利用。
相关文章推荐
- C++调用DotNet类库实现ISAPI Filter(C#)
- (C#,COM)调用某com组件报实现类无法强制转换成接口的的问题
- C++调用C#生成的DLL实现及注意事项
- c#调用C++写的dll导出类,如何实现
- 在C++中定义接口类,在C#中实现
- 使用IDispatch::Invoke函数在C++中调用C#实现的托管类库方法
- C# 调用SQL的存储过程的接口及实现
- 如何在linux C/C++语言中调用 sqlite 的函数接口来实现对数据库的管理(转)
- C# 调用C++写的dll的实现方法
- C#调用C++动态库接口
- (转)如何在linux C/C++语言中调用 sqlite 的函数接口来实现对数据库的管理
- C# 调用SQL的存储过程的接口及实现
- AE C#与C++接口调用差异总结
- C#实现调用C/C++中的函数
- 使用IDispatch::Invoke函数在C++中调用C#实现的托管类库方法
- c# 调用c++带有回调函数方法的实现
- 1_C# 实现VMS客户端——调用C++ SDK
- c#调用c++带有回调函数方法的实现
- C++调用C#的DLL实现方法
- C#调用C++的dll时,c++ dll函数接口中尽量不要用bool返回类型