再談在VB中呼叫VC 開發的DLL

2021-04-02 21:14:12 字數 3841 閱讀 3097

近日開發乙個程式,用到動態鏈結庫,在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能夠動態地裝入程序的位址空間,因此應用程式能夠在執行時確定需要執行什麼操作,然後裝入相應的 以便根據需要執行這些操作...