C++源碼如下:
—————————————————a.h—————————————————
#ifdef A_EXPORTS
#define A_API __declspec(dllexport)
#else
#define A_API __declspec(dllimport)
#endif
A_API int F(void);
—————————————————a.cpp—————————————————
#include "stdafx.h"
#include "a.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
A_API int F(void)
{
MessageBox(NULL, "1212", "1212", MB_OK);
return 0;
}
C#源碼函數原型聲明:
[DllImport("a.dll")]
public extern static int F();
調用後提示找不到進入點
在命令列用dumpbin /exports 看函數名:
dumpbin /exports a.dll
函數名不是"F"?而是"?F@@YAHXZ"
C#函式宣告寫成:
[DllImport("a.dll",EntryPoint="?F@@YAHXZ")]
public extern static int F();
這樣調用成功!
原因:在C++函式宣告時要將 extern "C" 添加在 DLL 函式宣告之前
主要注意包含 DllImport 的程式碼。此程式碼根據參數值通知編譯器,使之聲明位於 User32.dll 中的函數並將簽名中出現的所有字串(如參數或傳回值)視為 Unicode 字串。如果缺少 EntryPoint 參數,則預設值為函數名。另外,由於 CharSet 參數指定 Unicode,因此公用語言運行庫將首先尋找稱為 MessageBoxW(有 W 是因為 Unicode 規範)的函數。如果運行庫未找到此函數,它將根據呼叫慣例尋找 MessageBox 以及相應的修飾名。受支援的呼叫慣例只有 __cdecl 和 __stdcall。
當調用使用者定義的 DLL 中所包含的函數時,,如下所示:
// The function declaration in SampleDLL.h file
extern "C" SAMPLEDLL_API int fnSampleDLL(void);