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
表明被調用方清理堆棧。
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