近日開發乙個程式,用到動態鏈結庫,在vb
中呼叫時遇到了一些問題。我查了一些資料,也看了一下
csdn
上的文章,感覺這些文章對在
vb中呼叫
vc++
開發的dll
這一問題闡述得不夠詳細。因此在我的問題得到解決之餘,特為初接觸
dll的朋友們寫下這篇文章。
本文中關於呼叫約定的解決方法,也適用於解決其它程式語言之間
dll呼叫的相容問題。
①關於dll
的建立與呼叫 使用
vc++
的嚮導即可。具體操作如下:開啟選單「
file/new
」→選擇「
projects/win32 dynamic-link library
」→選擇「
a ****** dll project
」即可。這時系統會自動生成
3個檔案:
*.cpp
,stdafx.cpp
,stdafx.h。
之後將入口函式
dllmain()
補充完整,再新增你自定義的函式的**。如果你自定義的函式很多,可以將這些函式的宣告部分統一寫入乙個標頭檔案中。再在
.cpp
檔案首部用「
#include
」語句引入這個標頭檔案。注意函式宣告前要加上「
__declspec(dllexport)」。
(如果你建
dll時選擇的是第三種型別
(加入示例**
),則在函式宣告及定義前都要加上系統定義的巨集「
*_api
」。) 在vb
中用如下語句宣告:「
declare function
函式名
lib "
完整路徑
/檔名
.dll" [alias "
函式別名"
] (byval
變數1 as
型別1, byval
變數2 as
型別2,
…) as
型別3」,與呼叫
api函式類似。
注意:若在窗體**的「通用」部分使用,「
declare
」前要加「
private
」;若在
moudle
中使用,「
declare
」前要加「
public
」。若將
dll檔案放在「
/windows/system
」或「/winnt/system32
」目錄下,「
lib」後只寫出
dll主檔名即可。
具體的例項**見④(修正後的,可直接執行)。
②關於入口點
如上編寫
cipher.dll
,執行,出現錯誤資訊「找不到
dll入口點
(error 53)
」。出現這一錯誤的原因是
c++編譯器在編譯時對函式名
encrypt
作了修改。開啟快速檢視程式(
d:/winnt/system32/viewers/quikview.exe),
將cipher.dll
拖入檢視視窗,找到字段「
?encrypt@@yahhh@z」,
發現函式名被加了一串字元。
解決方法有二。第一,直接在
vb宣告中將「
?encrypt@@y ahhh@z
」作為別名放在「
alias
」後即可;
第二,在
cipher.dll
**中在語句「
__declspec(dllexport) int __stdcall encrypt(int p, int k); 」
前加上「
extern "c" 」
,編譯後,
用quikview
檢視,函式名變為「
_encrypt
」,之後再在
vb宣告中做相應調整即可。
(對於使用巨集的
dll,在「
#define
」語句中,對巨集「
cipher_api
」的替換值做更改即可。)
進行了③的更改後,程式又找不到入口點了。再用
quikview
檢視,發現函式名變為「
_encrypt@8
」。還有解決方法。在
cipher.dll
工程中新增乙個文字檔案,命名為「
cipher.def」,
新增**如④。編譯後再用
quikview
檢視,函式名變回「
encrypt
」,在vb
中呼叫,執行正常。
③關於呼叫約定
採用②中第二種解決方法,執行,出現錯誤資訊「
dll呼叫約定錯誤
(error 49)
」。原因是呼叫約定共有
4種方式:
__fastcall
、__pascal
、__stdcall
、__cdecl
,vc++
預設呼叫方式為
__cdecl
,而vb
預設呼叫方式則為
__stdcall
。解決方法是,更改**如下(限定呼叫方式):
extern 「c」
__declspec(dllexport)
int__stdcall encrypt(int p, int k);
…………
int
__stdcall encrypt(int p, int k)
④源**
cipher.dll:
cipher.cpp:
//引入預編譯標頭檔案
#include
「stdafx.h」 //
宣告我的函式
extern 「c」
__declspec(dllexport)
int
__stdcall encrypt( int p, int k );
//dll
入口函式
bool
apientry dllmain( handle
hmodule,
dword
ul_reason_for_call,
lpvoid
lpreserved
)
return true;
}
//我的函式
int
__stdcall encrypt ( int p, int k )
cipher.def:
library
cipher
exports
encrypt
編譯後,將
cipher.dll
複製到「
d:/winnt/system32
」目錄。 在
vb中呼叫:
option explicit
private
declare function
encrypt lib 「cipher」 _
(byval p as long, byval k as long) as long
private
sub form_load()
dimc as long
c = encrypt(24, 8)
text1.text = c
end sub
在VB應用程式中呼叫VC環境下開發的DLL
1.呼叫dll的優越性 動態鏈結庫 dll 作為windows作業系統的基礎,具有優越的應用效能 dll擴充套件了應用程式的特性。由於dll能夠動態地裝入程序的位址空間,因此應用程式能夠在執行時確定需要執行什麼操作,然後裝入相應的 以便根據需要執行這些操作。dll可以用多種語言進行編寫。例如用vb來...
在VB應用程式中呼叫VC環境下開發的DLL
1.呼叫dll的優越性 動態鏈結庫 dll 作為windows作業系統的基礎,具有優越的應用效能 dll擴充套件了應用程式的特性。由於dll能夠動態地裝入程序的位址空間,因此應用程式能夠在執行時確定需要執行什麼操作,然後裝入相應的 以便根據需要執行這些操作。dll可以用多種語言進行編寫。例如用vb來...
在VB應用程式中呼叫VC環境下開發的DLL
在vb應用程式中呼叫vc環境下開發的dll 1.呼叫dll的優越性 動態鏈結庫 dll 作為windows作業系統的基礎,具有優越的應用效能 dll擴充套件了應用程式的特性。由於dll能夠動態地裝入程序的位址空間,因此應用程式能夠在執行時確定需要執行什麼操作,然後裝入相應的 以便根據需要執行這些操作...