在C#中使用C/C++寫的DLLzz

來源:互聯網
上載者:User

在C#中使用C/C++寫的DLL

呵呵..,又到了我有想寫點東西的時候了.最近在論壇老是看見有朋友問

C/C++的程式如何在C#中使用?其實這是個很不錯的想法.代碼複用.不過

託管程式如何使用Unmanaged 程式碼呢?想想看,很自然就聯想到了DLL動態串連庫

把C/C++的代碼編譯成DLL,然後使用,這裡我假設我的C/C++代碼裡包含一個

函數,叫average(int av[])

申明如下:
extern "C" __declspec(dllexport) __cdecl int average(int *av);

實現嘛就更簡單了
__declspec(dllexport) __cdecl int average(int av[])
{
int i=0;
int sum=0;
  while(av)
{
  sum+=av[i];
   i++;
}
return sum/i;
}//隨手寫的也許有點問題

好了不管那麼多,讓我們來看看C#的代碼是如何?的,我想你應該想的到

是什麼?猜猜看,OK,我想你至少能想到兩個英文單詞dll import,是的你猜對了

DLLImport 屬性,就是它,看看它有些什麼,我可以用到,MSDN是最好的選擇.看見了嗎

是的,準確地說,DllImport 屬性具有下列行為:

它只能放置在方法聲明上。

它具有單個定位參數:指定包含被匯入方法的 dll 名稱的 dllName 參數。

它具有五個具名引數:
 

CallingConvention 參數指示進入點的呼叫慣例。如果未指定 CallingConvention,則使用預設值
CallingConvention.Winapi。

CharSet 參數指示用在進入點中的字元集。如果未指定 CharSet,則使用預設值 CharSet.Auto。

EntryPoint 參數給出 dll 中進入點的名稱。如果未指定 EntryPoint,則使用方法本身的名稱。

ExactSpelling 參數指示 EntryPoint 是否必須與指示的進入點的拼字完全符合。如果未指定
ExactSpelling,則使用預設值 false。

PreserveSig 參數指示方法的簽名應當被保留還是被轉換。當簽名被轉換時,它被轉換為一個具有
HRESULT 傳回值和該傳回值的一個名為 retval 的附加輸出參數的簽名。如果未指定 PreserveSig,則使
用預設值 true。

SetLastError 參數指示方法是否保留 Win32“上一錯誤”。如果未指定 SetLastError,則使用預設值

false。

它是一次性屬性類。

此外,用 DllImport 屬性修飾的方法必須具有 extern 修飾符。

是的,上面就是MSDN原文內容.好了繼續我們的例子,好了,先把我們上面的C代碼編譯成DLL

叫什麼呢?那就叫MYDLLTest好了.

[DllImport("MYDLLTest.dll",EntryPoint="average",ExactSpelling=false,CallingConvention=CallingConvention.Cdecl)]
static extern int average(int av[]);

好了,該是你找個地方寫一句的時候了

如:

int[5] i={1,2,3,4,5};
int j=average(i);

 

好了,你看到了,就是這樣的,可是事實上並沒有你想的那麼簡單.因為設計到很多問題

你看上面的例子中,int是在C#和C/C++中都有的,可是如果是char *呢?也許你會說string

可是你看在C/C++中這些都表示字串(char*,or wchar_t*,or BSTR, ..)那我們該怎麼辦?

想想看,還有些什麼?屬性嗎?是的,找找,對了我似乎想到一個單詞.Marshal恩..記得它嗎?

別告訴我,你會把它拼成馬歇爾.哈哈..開個玩笑是列集.我們在MSDN上輸入看看找到什麼了?

是的MarshalAs.看看MSDN上說些什麼?"指示應如何在Managed 程式碼和Unmanaged 程式碼之間封送資料"

哈哈.看來不錯呢.在看看下面的備忘:

可將該屬性應用於參數、欄位或傳回值。

該屬性為可選屬性,因為每個資料類型都有預設的封送處理行為。僅在可以將給定類型封送到多個類型時需要此屬性。例如,String 可能作為 LPStr、LPWStr、LPTStr 或 BStr 封送到Unmanaged 程式碼。預設情況下,字串作為 BStr 封送到 COM 方法。可將 MarshalAsAttribute 屬性應用於個別的欄位或參數,以使該字串作為 LPStr 而非 BStr 封送。有關如何使用此屬性的完整詳細資料,請參閱“資料封送處理規範”。

大多數情況下,該屬性只是使用 UnmanagedType 枚舉標識非管理的資料的格式,如下面的樣本所示。

[C#]
void MyMethod([MarshalAs(LPStr)] String s);
某些 UnmanagedType 枚舉需要附加資訊。例如,當 UnmanagedType 為 LPArray 時需要附加資訊。有關如何使用此屬性的完整說明,請參閱“資料封送處理規範”。

瞧見了,正是我們需要的對嗎?好了,我就寫怎麼多了,事實上,還有關於結構(struct)的

這就需要,你來完成了.希望對你有點協助.(完)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.