精品久久看,欧美成人久久一级c片免费,日本加勒比在线精品视频,国产一区二区三区免费大片天美,国产成人精品999在线,97理论三级九七午夜在线观看

東坡下載:內容最豐富最安全的下載站!

首頁編程開發VC(VC++) → C++和C#之間互相調用經驗詳談

C++和C#之間互相調用經驗詳談

相關文章發表評論 來源:本站時間:2011/4/23 6:27:38字體大小:A-A+

更多

作者:專題點擊:2007次評論:0次標簽: c語言

先說說程序大概組織邏輯。主程序有一套公用接口(其實就是純虛類),在加載DLL時候將此接口傳到DLL中,這樣子模塊在需要的時候就可以調用父的邏輯了,至于父調子,那就更簡單了,主程序有一個純虛類,子模塊都繼承此接口,并進行重寫,主程序按照一定的順序分別調用,這樣父與子的邏輯交互就完成了,這些對都是C++程序來說,這當然沒問題。現在問題是,要嵌入.NET的類庫,由此引發一系列問題。。。。。
軟件是以C++為父,DLL作為子的項目。
開發環境:WIN7 64BIT+VS2010+MFC+ATL+COM。
.NET環境下先以C#為例,其他的大部分一樣下,不排除做一些簡單或者復雜的修改。
下面正式開始把。
1. 動態加載 即父調子。
COM確實是好東西(他的褒與貶我們無作評論),她的語言無關性,不僅是我們實現動態加載的關鍵,更是實現加載其他.NET類庫的核心。如VB.NET。有了她,才是這一切皆有可能。
由于.NET下的類庫(DLL),和傳統的WIN DLL 不太一樣,畢竟托管的東西。她一些函數對外是不可見的,但對COM可見。因為我們就以COM方式定義一套接口,并把此接口當成普通C++的純虛接口,來完成父到子的調用。
這一點不論在理論上、代碼上都比較簡單,而且網上大多也是這樣子,所以我們直接上代碼。
如下為COM接口定義。
[ComVisible(true),
Guid("B86D71F4-FE07-4B60-8246-F5AE283ED2A3"),
InterfaceType(ComInterfaceType.InterfaceIsDual)
]
public interface IHMI
{
[PreserveSig, DispId(1)]
void OnCreate(int a);
[PreserveSig, DispId(2)]
void SetRect(int left, int top, int width, int height);
//其他接類似
}
[ ComVisible(true),
ClassInterface(ClassInterfaceType.AutoDual),
ProgId("xxxxxxx.xxxxxxx") //ProgId 主程序根據此,運行時動態創建。
]
C#在使用時要繼承并實現接口邏輯,如下類似。
public class CustomCOMClient : IHMI
{
public CustomCOMClient()
{
}
[DispId(1)]
public void OnCreate(int a)
{
//邏輯
}
[DispId(2)]
public void SetRect(int left, int top, int width, int height)
{
//邏輯
}
}
當然了,在建項目時,項目類型要為類庫。至此類庫部分已經完畢。接下來再看看主程序如何加載,以及如何調用把。
其中在動態創建時,ProgId是關鍵。這一部分對搞過COM,在加上ATL的人來說,可能太簡單了,‘可能’這個詞也許用的不太恰當,因為她不是‘可能’,她確實簡單。不信看代碼。
::CoInitialize(NULL);
const OLECHAR lpszProgID[]=OLESTR("xxxxxxx.xxxxxxx"); //ProgID
CComPtr m_NetCustomer;
HRESULT hr = m_NetCustomer.CoCreateInstance(lpszProgID);
if(SUCCEEDED(hr))
{
const LPCOLESTR szMember=OLESTR("OnCreate");
VARIANT v;
v.vt = VT_I4; v.lVal = 1024;
hr = m_NetCustomer.Invoke1(szMember,&v);
if(SUCCEEDED(hr))
{
}
}
::CoUninitialize();
怎么樣?沒有撒謊把,幾行代碼就把創建、調用搞定了。
郁悶,從C++拷出來代碼沒有格式,還的手工加。。。。
2. 回調 即子調父。
主程序肯定按照自己的邏輯順序依次調用子模塊的接口,如先創建、子的相關邏輯、最后銷毀。如果說在實際運用中,子模塊完全不會在調用父的相關功能,那么此時框架已經完全實現了,我們之前做的工作就是。難道不是嗎?,但應用程序往往也有父與子相互調用,下面就來看看,子如何回調父的功能把
前面也說過,子調父往往是這樣,從父身上分離出部分代碼,重新封裝一個dll,由子靜態綁定,這步最簡單、最方便。不過這顯然不是正道,讓人覺得別扭。
同時維護兩份相同功能代碼? 也許你會說,主程序從此也可以調用DLL啊,那不就一致了,你要真這樣說,我的回答是,“我只是在說明問題,不涉及到架構問題”
還有每個子模塊都靜態綁定這個DLL?
還有你在分離這個DLL時,如果依賴主程序太多,你怎么辦?
還有你能保證分離后的穩定性嗎?回帶來其他的問題嗎?
還有你僅僅是為了滿足功能,才這樣做的?
你覺得這樣看著順眼嗎?
等等。反正我覺得是古怪之急。
接下來就要需找其他替代方案了。
先考慮下在C++中這一部分是如何實現的把。 父傳給子一個虛接口(虛類),子在適當的時候調用。僅此而已。讓我們把調用函數想的深入一點。直接看匯編代碼把。
看代碼之前,還要先簡單說一下函數調用相關信息。在匯編層調用一個函數無非也就是JMP、CALL 之類的指令,若函數還有參數就是一些PUSH指令。好了知道這些就足夠了,下面看看在VC中的偽代碼。
__asm
{//類虛函數的匯編模擬調用,函數無參數、無返回值。
mov eax,xxxxx //存放函數地址
mov ecx,xxxxx //this指針
call eax //調用
}
這樣調用就完成了,其實真正的調用也如此,只不過指令多幾條而已。因為她要得到某些信息。
好了,如果說.NET支持內斂匯編,那我們完全可以自己模擬虛函數調用,不用在封裝什么DLL,這所有的一切都可以搞定,但可惜的時,常規下內斂匯編是不支持的。不錯,我說的是常規,那非常規呢?答案是肯定的。
關于內斂匯編網上也是一大片,底層思想是,在內存開辟一段空間,并放入相應指令,到時侯執行這一部分邏輯即可,這樣就可以完成內斂匯編了。
其中網上有一個封裝好的DLL(AsmClassLibrary.dll),提供接口編寫匯編代碼,用Reflector 查看了發現其最后執行采用遠程線程注入方式,對于嵌入一兩個模塊的,可以這樣做,但如果模塊很多的話,畢竟注入涉及到安全的問題,這一點不太好,當然這也太另類了,我可不想應用程序到處以這種方式來執行。
所以我們采用Marshal.GetDelegateForFunctionPointer方式。
因為從底層上講,是不分什么語言編寫,只認機器指令的,因此只要我們模擬的合理、正確,這一點是沒有問題的。
好了,現在我們目標很明確,用內斂方式在C#模擬虛函數的調用。
在給出代碼之前,也先說下思路。
根據之前所講以及常規知識,以下幾點是必須的。
A 類對象指針,因為我們要將此值給ECX。
B 成員函數地址,當然了,我們要CALL嘛。
C 參數,這值是在C#中使用的。
這就是主要內容,實現他們方式有很多種,以下是我的方案。
因為接口會很多,因此我將this指針、函數地址都放到數組中,然后在傳遞給C#中,其實按道理說,只傳遞一個this指針就夠了,其他部分應該在C#中實現,但操作指針C++中比較簡便,所以這部分代碼就在C++中做了。
得到this指針 太簡單啦,根據虛表布局得到其地址也很簡單。如下。
接口定義如下。
class CInterface
{
public:
virtual void test1( LPSTR p)
virtual void test2();
virtual void test3( int a);
};
得到this指針及成員函數地址。
CInterface *pInterface = new CInterface;
DWORD base_proc = (*((DWORD *)(pInterface))); //虛表指針
DWORD f1 = *(( DWORD *)base_proc); //第1個
DWORD f2 = *(( DWORD *)(base_proc + 4)); //第2個
DWORD f3 = *(( DWORD *)(base_proc + 8)); //第三個
到時將值賦值到SAFEARRAY 安全數組中,在傳遞到C#中。
看看在C#中時如何使用的把。當然這一部分的內斂、委托、開辟內存、托管到非托管轉換時少不了的,老規矩,看代碼把。
先定義委托和內斂。
//委托 參數分別為 this指針 成員函數地址 參數
delegate void testcall(int pthis, int pfun, int param);
byte[] codetest = {
// 0xCC,
0x8B, 0x5C, 0x24, 0x0C, //mov ebx,[esp+0Ch] 第三個參數 @@
0x8B, 0x44, 0x24, 0x08, //mov eax,[esp+08h] 函數地址
0x8B, 0x4C, 0x24, 0x04, //mov ecx,[esp+04h] this 指針
0x53, //push ebx 參數入棧 @@
0xFF, 0xD0, //call eax
0xC3 // ret
};
書寫內斂匯編當然可以考研我們的功底啦,看看你知道不知道底層是如何實現的、如何入棧、出棧、傳值、傳指針、傳引用、堆棧平衡等。還有一點,書寫匯編雖容易,但是機器指令我們并不都知道,山人自有妙計,匯編代碼貼到VC中,ALT+8看反匯編,在拷貝回來即可。
以上代碼中,完成接口第三個函數調用,帶有一個整形參數,并且傳值。
注釋掉@@部分完成接口第二個函數調用,無參數。
為了簡便都寫在一個里面,實際運用中,你可以按照不同格式分開。
接下來看看如何調用,,主要代碼如下。
VirtualAlloc。。。。。。之前肯定得先開辟內存啊
Marshal.Copy(codetest, 0, handle, codetest.Length);
testcall Customer = Marshal.GetDelegateForFunctionPointer(handle, typeof(testcall)) as testcall;
int bb = 22;
Customer (fun[0], fun[4], bb);
不錯,這就是子模塊調用父相關邏輯的主要實現。
3. 后話
這就是相互調用的所有部分嗎?這次答案是否定,實際上遠遠不至于此,我們此次實現的,只是最最基本的部分,尤其在參數上,我們用的最簡單的類型 int,實際使用中,對于兩者之間都存在的基本類型,還好說一點,當涉及到字符串、數組、結構體等這些類型時,真的會讓你很麻煩的,尤其是字符串,兩邊還不一樣。。。。。
其中對參數類型來說,我們用的是傳值方式,直接將值push,對于引用或者指針要把其地址push,就可以實現了,當然還是針對最基本的類型來說的。
對于字符串參數的,我用全局函數實現了一個接口(具體的可以看代碼),這樣其中大部分轉換操作,對我們就透明了,為何不自己搞?我有時間在補充進去把,這些就留給你們了,同樣你們搞出來之后要告訴我啊,這里給大家一個建議,處理字符串時,在C#中最好使用char數組,但在書寫內斂匯編時要注意,數組前面可有數組的大小,要偏移過去。
。。。。
。。。。
等把這一切都搞定之后,動態創建、嵌入VB的、C#的、WPF的以及她3D部分、硬件加速部分。。。。。。。。。
不錯,如此看來,現在才剛剛開始。。。。。。。。。。。。。
希望能給大家起到一個拋磚引玉作用。
最后附一個類型轉換的帖,供使用參考,類型轉換我就不啰嗦了。
http://topic.csdn.net/u/20090225/15/a6bc50ad-9721-4749-b189-dc4a4bc045a1.html
再附效果圖一張,圖中部分為嵌入C#的類型。

為了嵌入到父窗口上,使用了API SetParent 并且我有建了一個項目,就是封裝一些常用功能,具體看代碼把。

  • c語言學習app大全
  • c語言入門教程大全
  • C語言編程軟件下載
c語言學習app大全
(15)c語言學習app大全

C語言是一款編程的語言,很多軟件都是使用c語言編輯的,學好了c語言,以后找高新工作非常好找,在手機中安裝c語音學習軟件可以隨時利用空閑時間進行學習,cc語言學習app大全包含了豐富的學習軟件,從入門到精通的知識,基礎語法,視頻教程,二級考試題目都有涵蓋。

...更多>>
c語言入門教程大全
(14)c語言入門教程大全

c語言在編程中是很多的程序員都是需要學習的,那么現在就可以試試本站為你收集到最新的c語言入門教程大全,這里面包含了各種最新的c語言入門視頻教程,還有很多的c語言學習軟件,有在學習c語言的用戶都是可以來免費的下載的!

...更多>>
C語言編程軟件下載
(6)C語言編程軟件下載

C語言是計算機語言的基礎語言,學會了C語言,再去學習其它的語言就要簡單的多了!那么隨著想學習C語言的人越來越多了,如何學習C語言,學習C語言要用到那些軟件都是新手比較關心的問題了!今天本站給大家準備了一些C語言編程相關的軟件供大家來參考,覺得自己有需要,或者是想找些C語言編程軟件的朋友都可以來本站看看有沒有你需要的軟件!

...更多>>

相關評論

閱讀本文后您有什么感想? 已有 人給出評價!

  • 2791 喜歡喜歡
  • 2101 頂
  • 800 難過難過
  • 1219 囧
  • 4049 圍觀圍觀
  • 5602 無聊無聊
熱門評論
最新評論
昵稱:
表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
字數: 0/500 (您的評論需要經過審核才能顯示)

本類常用軟件

主站蜘蛛池模板: 成人小视频在线播放 | 国产在线成人精品 | 久久www免费人成看国产片 | 国产精品视频久久久久久 | 男人手机天堂 | 四虎影视最新网站在线播放 | 日韩精品视频在线免费观看 | 成年黄网站色视频免费观看 | 国产免费一区二区三区 | 99久久亚洲综合精品网站 | 日本高清二区视频久二区 | 美女性视频网站 | 日本中文字幕在线观看 | 国产日韩在线观看视频 | 亚洲aaa视频 | 国产精品久久久久网站 | 午夜国产在线 | 久久精品国产只有精品下载 | 婷婷丁香视频 | 4399影视免费观看高清直播 | 我爱52av好色| 国产高清在线视频一区二区三区 | 国产精品视频第一区二区三区 | 国产成人久久精品激情 | 精品久久久久久久九九九精品 | 男女视频网址 | 角斗士成1~3光荣战士在钱 | 日韩欧美在线中文字幕 | 婷婷丁香啪啪 | 五月一区二区久久综合天堂 | 色婷婷久久合月综 | 中文字幕热久久久久久久 | 久久国产精品99精品国产 | 欧美成人私人视频88在线观看 | 99re在线精品 | www.久久久 | 国产高清自拍一区 | 亚洲精品aaa揭晓 | 国产成人综合亚洲亚洲欧美 | 国产视频一区二区三区四区 | 深夜福利电影网 |