C#如何調(diào)用原生C++ COM對象詳解
前言
最近在工作中遇到一個問題,為了跨平臺在.net core中使用COM,不能使用Windows下的COM注冊機制,但是可以直接把IUnknown指針傳給C#,轉(zhuǎn)換為指針,再轉(zhuǎn)換為C#的接口(interface)。
做了這方面的研究,但最終我沒有使用這套技術(shù),因為對IDispatch::Invoke的分發(fā)太麻煩了,又不能借助ATL與VS開發(fā)環(huán)境的IDL能力。所以沒有繼續(xù)研究事件訂閱(C#是event,C++COM是IConnectionPoint)。
C++中需要做的:
簡單點,實現(xiàn)IDispatch就可以了,全面一點,實現(xiàn)IManagedObject或IProvideClassInfo,后者可是個大工程。
如果我們要實現(xiàn)C#中定義的接口,那么最好給(不給也可以,編譯器會給每個接口一個默認(rèn)的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; } };
再導(dǎo)出一個DLL的函數(shù)把指針給.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等平臺。架構(gòu)師,程序員應(yīng)合理利用。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。
上一篇:老生常談C++的單例模式與線程安全單例模式(懶漢/餓漢)
欄 目:C語言
本文標(biāo)題:C#如何調(diào)用原生C++ COM對象詳解
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/1939.html
您可能感興趣的文章
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用函數(shù)刪除字符
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求階乘
- 01-10如何判斷一個數(shù)是否為2的冪次方?若是,并判斷出來是多少次方
- 01-10如何判斷一個數(shù)是否為4的冪次方?若是,并判斷出來是多少次方
- 01-10如何查看進程實際的內(nèi)存占用情況詳解
- 01-10APUE筆記之:進程環(huán)境詳解
- 01-10如何尋找數(shù)組中的第二大數(shù)
- 01-10基于Linux系統(tǒng)調(diào)用--getrlimit()與setrlimit()函數(shù)的方法
- 01-10解析如何在C語言中調(diào)用shell命令的實現(xiàn)方法
- 01-10如何用C語言去除字符串兩邊的空字符


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機閱讀
- 04-02jquery與jsp,用jquery
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10C#中split用法實例總結(jié)
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-10delphi制作wav文件的方法
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文