c#調用c++動态庫一般我們這樣寫
CallingConvention 參數是c#調用c++的方式 是個枚舉 msdn解釋如下
Cdecl
調用方清理堆棧。這使您能夠調用具有 varargs 的函數(如 Printf),使之可用于接受可變數目的參數的方法。
FastCall
不支援此調用約定。
StdCall
被調用方清理堆棧。這是使用平台 invoke 調用非托管函數的預設約定。
ThisCall
第一個參數是 this 指針,它存儲在寄存器 ECX 中。其他參數被推送到堆棧上。此調用約定用于對從非托管 DLL 導出的類調用方法。
Winapi
從上面來看Winapi方式是根據系統自動選擇調用規約的。 而thisCall是對c++類的調用方法。 是以 一般情況下我們選擇Winapi就可以了。
c#調用dll另一個難點:資料類型轉換
<a href="http://wenku.baidu.com/link?url=SihlxtHC-HMcEhq3izpd2bux8rNaKOMTpu8NPqjdYlLSwYSV1CqNJdVbxkaZm7OqaaSTEK-KUJqX5jbtkdpnUZ_38No4tsrgqCsf7Th5dqK" target="_blank">http://wenku.baidu.com/link?url=SihlxtHC-HMcEhq3izpd2bux8rNaKOMTpu8NPqjdYlLSwYSV1CqNJdVbxkaZm7OqaaSTEK-KUJqX5jbtkdpnUZ_38No4tsrgqCsf7Th5dqK</a>
百度文庫這篇文章基本把c++與c#的對應資料類型總結完了。但是為什麼這裡還要說呢
1,百度文庫這篇文章,包括大部分度娘的類型轉換的資料中 對c++中的傳回值類型char[] 都轉換成了char[] 沒做任何改變。
c++中char占一個位元組,assic編碼。而c#中的char占2個位元組(我是在中文版的vs中測試的)。
如果這樣轉換就會出現問題,很容易發生越界,或者讀寫到受保護的記憶體等問題。
解決方法是 把char[] 變成c#中的byte[] ,再用Encoding.Assic.getstring方法轉換。
2,關于指針,c++所有的指針 在c#上用Intptr ,問題又來了。假如傳回的Intptr是個數組指針,在c#中我們怎麼讀取數組裡面的元素呢?
Marshal.Copy();
Marshal類是c#中專門把非托管記憶體轉換成托管記憶體的神器,不需要unsafe。 Marshal中copy方法是最最常用的方法。裡面有16個重載。能解決目前你能遇到的大部分問題。
msdn中對各個重載解釋如下
名稱
說明



<a href="http://technet.microsoft.com/zh-cn/library/ms146625(v=vs.95)">Copy(Byte[], Int32, IntPtr, Int32)</a>
安全關鍵。将一維的托管 8 位無符号整數數組中的資料複制到非托管記憶體指針。



<a href="http://technet.microsoft.com/zh-cn/library/ms146626(v=vs.95)">Copy(Char[], Int32, IntPtr, Int32)</a>
安全關鍵。将資料從一維的托管字元數組複制到非托管記憶體指針。



<a href="http://technet.microsoft.com/zh-cn/library/ms146627(v=vs.95)">Copy(Double[], Int32, IntPtr, Int32)</a>
安全關鍵。将資料從一維的托管雙精度浮點數組複制到非托管記憶體指針。



<a href="http://technet.microsoft.com/zh-cn/library/ms146628(v=vs.95)">Copy(Int16[], Int32, IntPtr, Int32)</a>
安全關鍵。将一維的托管 16 位有符号整數數組中的資料複制到非托管記憶體指針。



<a href="http://technet.microsoft.com/zh-cn/library/ms146629(v=vs.95)">Copy(Int32[], Int32, IntPtr, Int32)</a>
安全關鍵。将資料從一維的托管 32 位有符号整數數組複制到非托管記憶體指針。



<a href="http://technet.microsoft.com/zh-cn/library/ms146630(v=vs.95)">Copy(Int64[], Int32, IntPtr, Int32)</a>
安全關鍵。将一維的托管 64 位有符号整數數組中的資料複制到非托管記憶體指針。



<a href="http://technet.microsoft.com/zh-cn/library/ms146631(v=vs.95)">Copy(IntPtr, Byte[], Int32, Int32)</a>
安全關鍵。将資料從非托管記憶體指針複制到托管 8 位無符号整數數組。



<a href="http://technet.microsoft.com/zh-cn/library/ms146632(v=vs.95)">Copy(IntPtr, Char[], Int32, Int32)</a>
安全關鍵。将資料從非托管記憶體指針複制到托管字元數組。



<a href="http://technet.microsoft.com/zh-cn/library/ms146633(v=vs.95)">Copy(IntPtr, Double[], Int32, Int32)</a>
安全關鍵。将資料從非托管記憶體指針複制到托管雙精度浮點數組。



<a href="http://technet.microsoft.com/zh-cn/library/ms146634(v=vs.95)">Copy(IntPtr, Int16[], Int32, Int32)</a>
安全關鍵。将非托管記憶體指針中的資料複制到托管 16 位有符号整數數組。



<a href="http://technet.microsoft.com/zh-cn/library/ms146635(v=vs.95)">Copy(IntPtr, Int32[], Int32, Int32)</a>
安全關鍵。将非托管記憶體指針中的資料複制到托管 32 位有符号整數數組。



<a href="http://technet.microsoft.com/zh-cn/library/ms146636(v=vs.95)">Copy(IntPtr, Int64[], Int32, Int32)</a>
安全關鍵。将非托管記憶體指針中的資料複制到托管 64 位有符号整數數組。



<a href="http://technet.microsoft.com/zh-cn/library/a53bd6cz(v=vs.95)">Copy(IntPtr, Single[], Int32, Int32)</a>
安全關鍵。将資料從非托管記憶體指針複制到托管單精度浮點數組。



<a href="http://technet.microsoft.com/zh-cn/library/ez2e4559(v=vs.95)">Copy(Single[], Int32, IntPtr, Int32)</a>
安全關鍵。将資料從一維的托管單精度浮點數組複制到非托管記憶體指針。
<a href="http://technet.microsoft.com/zh-cn/library/system.runtime.interopservices.marshal.copy(v=vs.95)#mainBody"> </a>
我們也可以使用共享記憶體的方式進行操作。部分代碼如下
<a href="http://files.cnblogs.com/Bonker/Win32Interop.zip" target="_blank">這裡是共享記憶體的輔助類 主要是一些api函數</a>
其實Intptr本質也是一個Int,Int在c#中和Int32是一樣的。是以基本上指針,Long,int在c#中都是int。隻是這樣些 友善大家知道他是c++中的什麼類型,友善轉換而已。
3,c++中的函數指針 與c#中的委托
這是c++中對函數指針的定義
對應c#中的例子如下
4,我們知道int是占4個位元組的。
下面這個是c++的一個方法
假如我們把此函數翻譯成c#中的下面這個函數
我們在c#調用此方法
uint16 m_HiWi_temp = (uint)BCamera.CAMER_GetPropery(m_hCamer, CMRCTL.OUT_SIZE);
發現一個很有趣的問題,此處調用沒有問題。也有值,但是他是取的int32中4個位元組的2個位元組。
我們看原本c++對此函數的調用
本來CAMER_GetPropery函數隻傳回了一個long類型。c++中通過指針的轉換。把long類型轉換成了 pulong,也是ulong的數組。
那c#中怎麼我們該怎麼調用呢
這裡舉這個例子是說c++有時真的就是傳回一個int類型,但是在c++中可以輕松把int類型通過指針輕松轉換成兩個uint16的數組。是以c#中我們再轉換的時候一定有注意了。
總結:其實資料類型的轉換主要是對資料存儲空間的轉換,c++中的資料類型占用多大的空間,隻要轉換成c#中占同等空間的資料類型就可以了。隻是c#看哪種資料類型在操作相應的操作友善些。
QQ:519841366
本頁版權歸作者和部落格園所有,歡迎轉載,但未經作者同意必須保留此段聲明,
且在文章頁面明顯位置給出原文連結,否則保留追究法律責任的權利