VC PB dll
VC6中的函數調用約定:
調用約定 堆棧清除 參數傳遞
__cdecl 調用者 從右到左,通過堆棧傳遞
__stdcall 函數體 從右到左,通過堆棧傳遞
__fastcall 函數體 從右到左,優先使用寄存器(ECX,EDX),然後使用堆棧
thiscall 函數體 this指針默認通過ECX傳遞,其它參數從右到左入棧
建議在不同語言間的調用中(如DLL)最好採用stdcall調用約定,因爲它在語言間兼容性支持最好;
在調用DLL裏面的函數時候,要用extern 聲明是外部變量
比如 extern int add(int num1,int num2);
在編譯DLL時,要把編譯的LIB文件放到執行文件的目錄下,並且在編譯執行文件的時候要連接LIB文件。
在定義DLL的時候要定義導出函數就要在該函數前面加__declspec(DLLexport)時,
C++編譯器爲了支持函數的重載會進行函數名字改編,當可執行模塊執行該函數時由於找不到該函數的名字,
於是調用就會出現錯誤!當使用extern “C”時就可以告訴編譯器不必修改函數名和變量名。
這樣就可以用C++或C編譯器程序調用該函數。或者使用def文件.
// def文件
LIBRARY dlltest
EXPORTS
add
subtract
和編寫一般的DLL方法相同,需要注意以下兩點:
(1)調用約定
C函數有_stdcall、_cdecl、_fastcall等多種調用約定,調用約定用來說明函數參數的壓棧順序和由誰(函數自身還是調用者)來修改堆棧。關於調用約定的詳細說明,請參考我轉載的另一篇文章。
編寫供PB調用DLL,請使用_stdcall調用約定,如下所示:
extern "C" _declspec(dllexport) int _stdcall GetInt(char* name)
{
...
}
(2)def文件
在VC++中,如果生成DLL可以不使用.def文件,只需要在VC++的函數定義前加__declspec(dllexport)修飾就可以了。生成的DLL VC++用戶可以直接使用,但PB、VB等用戶使用會遇到函數名轉換的問題。因爲VC++對於__declspec(dllexport)聲明的函數會進行名稱轉換,如下面的函數:
__declspec(dllexport) int _stdcall GetStr()
編譯後會轉換爲 GetStr@0,這樣在PB、VB中聲明函數時應該聲明GetStr@0,
如果函數帶有參數,轉換後的函數名將更加複雜,這使PB、VB用戶使用起來很不方便。在def文件中由EXPORT輸出函數可解決這個問題。
如dll要輸出如下兩個函數:
extern "C" _declspec(dllexport) int _stdcall GetInt(char* name);
extern "C" _declspec(dllexport) char* _stdcall GetStr(int id);
則def文件書寫如下(TEST爲工程名):
LIBRARY "TEST"
DESCRIPTION 'TEST Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
GetInt @1
GetStr @2
編譯生成DLL後,在PB中要調用GetStr函數,只需做如下聲明即可:
function string GetStr(int a) library("TEST.dll");
注意,如果您建的是Win32 Dynamic-Link Library 工程,def文件需要自己創建,然後把它加入工程,def文件名需和工程名相同。如您的工程名爲test,則創建test.def。
右邊是PB調用C++ DLL的程序範例地址:http://download.csdn.net/detail/youyongyoumou/8763723