在非託管C++/CLI引用託管對象

來源:互聯網
上載者:User

一個技術研究工作,需要使用native代碼構建一個dll,並實現其中的函數:

HRESULT WMCreateStreamForURL( LPCWSTR pwszURL,
BOOL* pfCorrectSource,
IStream** ppStream
)

因為未來項目準備使用C#編程,所以很自然想到了C++/CLI來實現這個dll,並且將調用轉寄到C#的實現裡。做起來很容易,我用C#實現了一個StreamManager,負責檢查傳入的url並返回相應的IStream實現。

這裡環境為VS2005。用C#實現的工程叫做protocol,用C++/CLI實現的工程名字為protocol_stub(必須使用/cli參數編譯)。

首先遇到的是C++/CLI中的Managed 程式碼和Unmanaged 程式碼的相互調用問題,查閱了一下協助,發現使用#pragma managed和#pragma unmanaged就可以劃定函數的編譯方式到底是native還是cli。

其次,在C++中調用StreamManager時候報告找不到。經過檢查,發現要在C++工程中添加對protocol的引用,同時,要在C++代碼的managed部分使用指令

#pragma managed

#import "protocol.tlb" raw_interfaces_only
using namespace protocol;
using namespace System;
using namespace System::Runtime::InteropServices;

這樣才可以正常編譯代碼StreamManager^ mgr = StreamManager::Instance;其中,protocol.tlb是用VS內建工具TlbExp產生的。

第三個問題是匯出.net對象的問題。兩個工程可以正常編譯,但是測試回合時候卻報告異常。經過檢查,原來是System::Runtime::InteropServices::ComTypes::IStream雖然就是IStream的實現,但是卻無法進行強制轉換。用如下的代碼雖然編譯可以過去,但是不能工作

ComTypes::IStream^ s = mgr->getStream(url);
cli::pin_ptr<ComTypes::IStream^> p = &s;
*ppStream = (IStream*)p;

經過查詢,發現解決的方法很簡單,代碼如下:

ComTypes::IStream^ s = mgr->getStream(url);
IntPtr^ handle = Marshal::GetComInterfaceForObject(s, ComTypes::IStream::typeid);
*ppStream = (IStream*)handle->ToPointer();

這樣,整個工作順利完成。

總結:C++/CLI經過vs2003之後變動很大,從醜小鴨終於變成了白天鵝,不僅實現了C++和CLI的無縫整合,而且保留了原先C++文法的優美和簡潔。因為可以支援本地代碼和CLI代碼的混合調用,不僅可以充分利用Windows系統和.net的資源,而且因為本地代碼的不可反編譯性,使得C++/CLI天生就有了安全保密性。看來要在項目中的一些關鍵演算法部分使用C++了。

另外,幾個要注意的地方:

C#中xxx.getType()或者typeof(ClassXXX)在C++/CLI中對應代碼是 ClassXXX::typeid
在C++/CLI中#import 比較重要,要注意
在C#中,所有對象天生就是COM對象(好在我一直沒有弄錯)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.