如何用VC編寫供PB調用的DLL[轉帖]2008-11-01 12:40
VC PB dll和編寫一般的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。//然後將def加入VS2005,VC6工程中,只要有DEF檔案並將其添加到工程中,VC6就可以自動地產生DLL與其相應的Lib檔案了。 但是VS2005不一樣,需要指定DEF檔案 工程 > 屬性中的連結器,然後找到"輸入"這一項. 在 "模組定義檔案" 中輸入 testdll.def. // 在C++ Builder中編寫DLL的時候函數如果給外部程式調用應這樣聲明: extern "C" __declspec(dllexport) char * __stdcall Test(char * StrTest) 在PB中如果調用這樣的DLL檔案應這樣聲明: FUNCTION String Test(String StrTest) LIBRARY "Test.dll" 如果不需要傳回值: subroutine Test(String StrTest) LIBRARY "Test.dll" 如果要是以函數參數的形式返回在PB中的參數可以這樣定義 subroutine Test(ref char StrTest[]) LIBRARY "Test.dll" FUNCTION關鍵字一般用於聲明WIN32API函式宣告 subroutine一般用於調用外部DLL(外部函數一般採用部分函數參數作為傳回值的形式) C++Builde中呼叫慣例有 __fastcall、__pascal、__stdcall、__cdecl 四個關鍵字 編寫DLL與編寫其他函數沒什麼區別,如果要表露出函數給外部程式用應用__stdcall關鍵字以指定產生的DLL具有相容性 |