資源描述:
《C++和C#之間互相調(diào)用經(jīng)驗(yàn)詳談》由會員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫。
1、C++和C#之間互相調(diào)用經(jīng)驗(yàn)詳談先說說程序大概組織邏輯。主程序有一套公用接口(其實(shí)就是純虛類),在加載DLL時候?qū)⒋私涌趥鞯紻LL中,這樣子模塊在需要的時候就可以調(diào)用父的邏輯了,至于父調(diào)子,那就更簡單了,主程序有一個純虛類,子模塊都繼承此接口,并進(jìn)行重寫,主程序按照一定的順序分別調(diào)用,這樣父與子的邏輯交互就完成了,這些對都是C++程序來說,這當(dāng)然沒問題?,F(xiàn)在問題是,要嵌入。NET的類庫,由此引發(fā)一系列問題…… 軟件是以C++為父,DLL作為子的項目。 開發(fā)環(huán)境:WIN764BIT+VS2010+MFC+ATL+COM. .N
2、ET環(huán)境下先以C#為例,其他的大部分一樣下,不排除做一些簡單或者復(fù)雜的修改。 下面正式開始把?! ?.動態(tài)加載即父調(diào)子?! OM確實(shí)是好東西(他的褒與貶我們無作評論),她的語言無關(guān)性,不僅是我們實(shí)現(xiàn)動態(tài)加載的關(guān)鍵,更是實(shí)現(xiàn)加載其他。NET類庫的核心。如VB.NET.有了她,才是這一切皆有可能。 由于。NET下的類庫(DLL),和傳統(tǒng)的WINDLL不太一樣,畢竟托管的東西。她一些函數(shù)對外是不可見的,但對COM可見。因?yàn)槲覀兙鸵訡OM方式定義一套接口,并把此接口當(dāng)成普通C++的純虛接口,來完成父到子的調(diào)用?! ∵@一點(diǎn)不論在理論上
3、、代碼上都比較簡單,而且網(wǎng)上大多也是這樣子,所以我們直接上代碼?! ∪缦聻镃OM接口定義?! ComVisible(true), Guid("B86D71F4-FE07-4B60-8246-F5AE283ED2A3"), InterfaceType(ComInterfaceType.InterfaceIsDual) ] publicinterfaceIHMI { [PreserveSig,DispId(1)] voidOnCreate(inta); [PreserveSig,DispId(2)] voidSet
4、Rect(intleft,inttop,intwidth,intheight); //其他接類似 } [ComVisible(true), ClassInterface(ClassInterfaceType.AutoDual), ProgId("xxxxxxx.xxxxxxx")//ProgId主程序根據(jù)此,運(yùn)行時動態(tài)創(chuàng)建。 ] C#在使用時要繼承并實(shí)現(xiàn)接口邏輯,如下類似。 publicclassCustomCOMClient:IHMI { publicCustomCOMClient() { } [Dis
5、pId(1)] publicvoidOnCreate(inta) { //邏輯 } [DispId(2)] publicvoidSetRect(intleft,inttop,intwidth,intheight) { //邏輯 } } 當(dāng)然了,在建項目時,項目類型要為類庫。至此類庫部分已經(jīng)完畢。接下來再看看主程序如何加載,以及如何調(diào)用把。 其中在動態(tài)創(chuàng)建時,ProgId是關(guān)鍵。這一部分對搞過COM,在加上ATL的人來說,可能太簡單了,'可能'這個詞也許用的不太恰當(dāng),因?yàn)樗皇?可能',她確實(shí)簡單。不信看代碼
6、。 ::CoInitialize(NULL); constOLECHARlpszProgID[]=OLESTR("xxxxxxx.xxxxxxx");//ProgID CComPtrm_NetCustomer; HRESULThr=m_NetCustomer.CoCreateInstance(lpszProgID); if(SUCCEEDED(hr)) { constLPCOLESTRszMember=OLESTR("OnCreate"); VARIANTv; v.vt=VT_I4;v.lVal=1024; h
7、r=m_NetCustomer.Invoke1(szMember,&v); if(SUCCEEDED(hr)) { } } ::CoUninitialize(); 怎么樣?沒有撒謊把,幾行代碼就把創(chuàng)建、調(diào)用搞定了。 郁悶,從C++拷出來代碼沒有格式,還的手工加…2.回調(diào)即子調(diào)父?! ≈鞒绦蚩隙ò凑兆约旱倪壿嬳樞蛞来握{(diào)用子模塊的接口,如先創(chuàng)建、子的相關(guān)邏輯、最后銷毀。如果說在實(shí)際運(yùn)用中,子模塊完全不會在調(diào)用父的相關(guān)功能,那么此時框架已經(jīng)完全實(shí)現(xiàn)了,我們之前做的工作就是。難道不是嗎?,但應(yīng)用程序往往也有父與子相互調(diào)用,下
8、面就來看看,子如何回調(diào)父的功能把 前面也說過,子調(diào)父往往是這樣,從父身上分離出部分代碼,重新封裝一個dll,由子靜態(tài)綁定,這步最簡單、最方便。不過這顯然不是正道,讓人覺得別扭。 同時維護(hù)兩份相同功能代碼?也許你會說,主程序從此也可以調(diào)用DLL啊