整體描述:
ATL做的COM組件,C#做的界面。
C#呼叫COM組件進行業務處理,C++需要回呼到C#界面。
基本打通了,回呼引數如果是普通引數的話,如LONG*的話,沒問題
但如果是結構的話,
hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL);
這句話會回傳失敗:有一個引數無效
IDL:
struct Point
{
LONG x, y;
};
struct PROPERTY
{
struct Point pt;
FLOAT x;
FLOAT y;
FLOAT z;
FLOAT f;
};
dispinterface IEvents
{
methods:
[id(1)] HRESULT GetProperty([in] int index, [in, out] struct PROPERTY* prop);
};
考慮到結構后面一定會經常變化或擴充,所以不希望把引數展開一個個用指標來寫回呼 :)
類似的問題別人也早問了,沒得到解決方法:
http://bbs.csdn.net/topics/390592325
uj5u.com熱心網友回復:
C#不熟,純屬個人意見struct _tagMySruct_t
{
int cbSize;
LONG ……
}MYSTRUCT, *LPSTRUCT;
傳遞一個 void *指標, 然后強制轉換
uj5u.com熱心網友回復:
我在IDL里定義了結構,這樣C#與C++結構容易互通。
否則c#還要自己定義結構,描述比C++復雜。
uj5u.com熱心網友回復:
不要做A語言代碼修改為B語言代碼的無用功。也不要做用A語言代碼直接呼叫B語言代碼庫這樣復雜、這樣容易出錯的傻事。
只需讓A、B語言代碼的輸入輸出重定向到文本檔案,或修改A、B語言代碼讓其通過文本檔案輸入輸出。
即可很方便地讓A、B兩種語言之間協調作業。
比如:
A將請求資料寫到檔案a.txt,寫完后改名為aa.txt
B發現aa.txt存在時,讀取其內容,呼叫相應功能,將結果寫到檔案b.txt,寫完后洗掉aa.txt,再將b.txt改名為bb.txt
A發現bb.txt存在時,讀取其內容,讀完后洗掉bb.txt
以上A可以替換為任何一種開發語言或開發環境,B可以替換為任何一種與A不同的開發語言或開發環境。
除非A或B不支持判斷檔案是否存在、檔案讀寫和檔案更名。
但是誰又能舉出不支持判斷檔案是否存在、檔案讀寫和檔案更名的開發語言或開發環境呢?
可以將臨時檔案放在RamDisk上提高效率減少磨損磁盤。
資料的結構很復雜的話,文本檔案的格式問題可參考json或xml
共享臨時文本檔案這種行程之間的通訊方法相比其它方法的優點有很多,下面僅列出我現在能想到的:
·行程之間松耦合
·行程可在同一臺機器上,也可跨機,跨作業系統,跨硬體平臺,甚至跨國。
·方便除錯和監視,只需讓第三方或人工查看該臨時文本檔案即可。
·方便在線開關服務,只需洗掉或創建該臨時文本檔案即可。
·方便實作分布式和負載均衡。
·方便佇列化提供服務,而且幾乎不可能發生佇列滿的情況(除非硬碟空間滿)
·……
“跨語言、跨機,跨作業系統,跨硬體平臺,跨國,跨*.*的”苦海無邊,
回頭是“使用共享純文本檔案進行資訊交流”的岸!
uj5u.com熱心網友回復:
你的說法讓人很無語,真的
1.COM是很標準的規范,應用也很廣泛,它本身就支持跨語言,現在碰到一點難點就放棄,不是開發者風格
2.你覺得檔案讀寫是可以滿足一般的要求,但是如果是對高實時性、資料量較大的需求,文本讀寫并不合適
3.實作文本通信,還搞出記憶體檔案了,開發效率并不高,對后期長遠來看,我覺得不是最好的選擇。
uj5u.com熱心網友回復:
不用結構體,用SAFEARRAY傳遞陣列的方式uj5u.com熱心網友回復:
COM支持跨語言?能跨
Apple ][
C51
DOS
Linux
Android
iOS
VxWorks
Arduino
……
嗎?
無profiler不要談效率!!尤其在這個云計算、虛擬機、模擬器、CUDA、多核 、多級cache、指令流水線、多種存盤介質、……滿天飛的時代!

uj5u.com熱心網友回復:
那C#那端也按陣列訪問了唄,就是可讀性會很差,隨著結構越來越復雜。
看網上還有轉成BSTR,不知道是說用BSTR當記憶體塊傳資料(BSTR本身有大小),還是轉成真正的字串描述:format?
我用網上的其他人的方法,把整個結果序列化進VT結構,都是回傳出錯,不知道是COM服務端自身處理引數時出錯,還是客戶端C#在轉換成C#可用的資料時出錯。。。
uj5u.com熱心網友回復:
我用C#呼叫COM的GetXXX或SetXXX類方法,使用結構是沒問題的,證明了COM在處理結構引數是能搞定的。
就是到了回呼部分結構有問題。
不知道是不會用,還是MS實作上沒做好。。。
uj5u.com熱心網友回復:
頂頂頂頂頂頂頂頂uj5u.com熱心網友回復:
結構體改為一個獨立的COM物件就解決了,回傳的是COM物件介面指標的變體值,然后C#把該COM物件介面變體指標強制轉換為實際的COM物件型別指標uj5u.com熱心網友回復:
這樣感覺寫代碼就比較復雜了
c#呼叫我C++寫的com,結構傳進傳出,都很正常,證明各種引數序列化是正常的,為啥到連接點就不行了,奇怪。
uj5u.com熱心網友回復:
樓主我想問一下怎樣呼叫com組件中引數是結構體指標的介面。uj5u.com熱心網友回復:
比較簡單的方法是把結構物件的每個元素變為一個變體陣列的各個元素,然后把這個變體陣列組合為一個變體;然后在C#中強制轉換為object[] 型別,這樣就可以看到原來結構物件中的每個元素了
第二種方法就是實際傳送的結構物件也變成一個COM組件物件,然后作為變體發送給C#,C#中就是一個object物件
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/55949.html
上一篇:求幫忙!!求幫忙!!ADO連接Access,想把圖片地址那資料格式改成超鏈接。
下一篇:MFC界面白屏
