pb調用vc dll約定

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章