天天看點

c#調用c++動态庫的一些了解

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中對各個重載解釋如下

名稱

說明

c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解

<a href="http://technet.microsoft.com/zh-cn/library/ms146625(v=vs.95)">Copy(Byte[], Int32, IntPtr, Int32)</a>

安全關鍵。将一維的托管 8 位無符号整數數組中的資料複制到非托管記憶體指針。

c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解

<a href="http://technet.microsoft.com/zh-cn/library/ms146626(v=vs.95)">Copy(Char[], Int32, IntPtr, Int32)</a>

安全關鍵。将資料從一維的托管字元數組複制到非托管記憶體指針。

c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解

<a href="http://technet.microsoft.com/zh-cn/library/ms146627(v=vs.95)">Copy(Double[], Int32, IntPtr, Int32)</a>

安全關鍵。将資料從一維的托管雙精度浮點數組複制到非托管記憶體指針。

c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解

<a href="http://technet.microsoft.com/zh-cn/library/ms146628(v=vs.95)">Copy(Int16[], Int32, IntPtr, Int32)</a>

安全關鍵。将一維的托管 16 位有符号整數數組中的資料複制到非托管記憶體指針。

c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解

<a href="http://technet.microsoft.com/zh-cn/library/ms146629(v=vs.95)">Copy(Int32[], Int32, IntPtr, Int32)</a>

安全關鍵。将資料從一維的托管 32 位有符号整數數組複制到非托管記憶體指針。

c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解

<a href="http://technet.microsoft.com/zh-cn/library/ms146630(v=vs.95)">Copy(Int64[], Int32, IntPtr, Int32)</a>

安全關鍵。将一維的托管 64 位有符号整數數組中的資料複制到非托管記憶體指針。

c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解

<a href="http://technet.microsoft.com/zh-cn/library/ms146631(v=vs.95)">Copy(IntPtr, Byte[], Int32, Int32)</a>

安全關鍵。将資料從非托管記憶體指針複制到托管 8 位無符号整數數組。

c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解

<a href="http://technet.microsoft.com/zh-cn/library/ms146632(v=vs.95)">Copy(IntPtr, Char[], Int32, Int32)</a>

安全關鍵。将資料從非托管記憶體指針複制到托管字元數組。

c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解

<a href="http://technet.microsoft.com/zh-cn/library/ms146633(v=vs.95)">Copy(IntPtr, Double[], Int32, Int32)</a>

安全關鍵。将資料從非托管記憶體指針複制到托管雙精度浮點數組。

c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解

<a href="http://technet.microsoft.com/zh-cn/library/ms146634(v=vs.95)">Copy(IntPtr, Int16[], Int32, Int32)</a>

安全關鍵。将非托管記憶體指針中的資料複制到托管 16 位有符号整數數組。

c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解

<a href="http://technet.microsoft.com/zh-cn/library/ms146635(v=vs.95)">Copy(IntPtr, Int32[], Int32, Int32)</a>

安全關鍵。将非托管記憶體指針中的資料複制到托管 32 位有符号整數數組。

c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解

<a href="http://technet.microsoft.com/zh-cn/library/ms146636(v=vs.95)">Copy(IntPtr, Int64[], Int32, Int32)</a>

安全關鍵。将非托管記憶體指針中的資料複制到托管 64 位有符号整數數組。

c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解

<a href="http://technet.microsoft.com/zh-cn/library/a53bd6cz(v=vs.95)">Copy(IntPtr, Single[], Int32, Int32)</a>

安全關鍵。将資料從非托管記憶體指針複制到托管單精度浮點數組。

c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解
c#調用c++動态庫的一些了解

<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

本頁版權歸作者和部落格園所有,歡迎轉載,但未經作者同意必須保留此段聲明,

且在文章頁面明顯位置給出原文連結,否則保留追究法律責任的權利