程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#程序調用非托管C++ DLL文件的方法

C#程序調用非托管C++ DLL文件的方法

編輯:C#入門知識

C++中的函數聲明

  1 extern "C" __declspec(dllexport) int __stdcall testfunc(char* astr,int* a);

  

extern ”C”

  通常來說,C++編譯器可能會改變函數和變量的名字,從而導致嚴重的鏈接程序問題。例如,假設使用C++編寫一個DLL,當創建DLL時,Microsoft的編譯器就會改變函數的名字。函數名將被設置一個前導下劃線,再加上一個@符號的前綴,後隨一個數字,表示作為參數傳遞給函數的字節數。例如,下面的函數是作為DLL的輸出節中的_MyFunc@8輸出的:

  1 __declspec(dllexport) LONG __stdcall MyFunc(int a, int b);

  如果用另一個供應商的工具創建了一個可執行模塊,它將設法鏈接到一個名叫MyFunc的函數,該函數在Microsoft編譯器已有的DLL中並不存在,因此鏈接將失敗。

  使用extern “C”關鍵字可以使編譯器按照C語言的方式編譯DLL文件,即編譯時不改變函數名。

 

__declspec(dllexport)

  在 32 位編譯器版本中,可以使用__declspec(dllexport) 關鍵字從DLL導出數據、函數、類或類成員函數。__declspec(dllexport) 會將導出指令添加到對象文件中,因此不需要使用.def文件。

  若要導出函數,__declspec(dllexport) 關鍵字必須出現在調用約定關鍵字的左邊(如果指定了關鍵字)。例如:

  1 __declspec(dllexport) void __cdecl Function1(void);

 

__stdcall

  表明被調用方清理堆棧。

 

C#中的函數聲明

  1 using System.Runtime.InteropServices; 2        3    4 public class Program 5 { 6 [DllImport(@"E:Projects estdlldebug estdll.dll")] 7 public static extern int testfunc(StringBuilder abuf,ref int a); 8 }

 

using System.Runtime.InteropServices;

  System.Runtime.InteropServices 命名空間提供各種各樣支持 COM interop 及平台調用服務的成員,使程序可以與非托管代碼進行交互操作。

 

[DllImport(“dllfile path”)]

  代碼中DllImport關鍵字作用是告訴編譯器入口點在哪裡,並將打包函數捆綁在這個類中。在聲明的時候還可以添加幾個屬性:

  1 [DllImport("MyDLL.dll", 2 EntryPoint="mySum", 3 CharSet=CharSet.Auto, 4 CallingConvention=CallingConvention.StdCall)]

  EntryPoint: 指定要調用的 DLL 入口點。默認入口點名稱是托管方法的名稱 。
  CharSet: 控制名稱重整和封送 String 參數的方式 (默認是UNICODE)
  C

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved