vb呼叫vc dll檔案

2021-06-01 13:57:09 字數 3836 閱讀 5435

① 關於dll的建立與呼叫使用vc++的嚮導即可。具體操作如下:開啟選單「file\new」→選擇「projects\win32 dynamic-link library」→選擇「a ****** dll project」即可。這時系統會自動生成3個檔案:*.cpp,stdafx.cpp,stdafx.h。

之後將入口函式dllmain()補充完整,再新增你自定義的函式的**。如果你自定義的函式很多,可以將這些函式的宣告部分統一寫入乙個標頭檔案中。再在.cpp檔案首部用「#i nclude」語句引入這個標頭檔案。注意函式宣告前要加上「__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 453)」在除錯中耗費1.5天時間在網上找資料解決此問題。

網上指出可能原因:

1。沒有注意函式名大小寫。dll中的函式與vb中的函式宣告必須大小寫完全相同。

2。沒有宣告入口函式。需要在dll的.def檔案中加上入口函式。

如:exports

setdata @1

getdata @2

如果dll工程原本沒有使用.def檔案,可以自己建立乙個加入到工程中。

3。採用了c++編譯方式

在c++中編譯函式時會將函式名進行轉換。解決的方法有兩個:

(1)如果沒有使用c++的類,可以將.cpp檔案改名為.c,就不進行這種轉換了。

(2)在函式定義前加上extern "c",如:

extern "c" void _stdcall kk(double k)

需要指出的是,vc++允許不編寫.def檔案,而是在函式定義前加

_declspec(dllexport)修飾符,這樣的函式也可以被外部程式呼叫。

實際問題所在:(.def是關鍵)

排查完上面可能存在的問題後,

發現vb呼叫時依舊是「找不到dll入口點」

檢視vc程式結構,發現編譯時沒有將.def檔案載入進工程裡面。

這就導致生成的dll檔案沒有外部介面。總結自己還是vc不熟悉所致。

出現這一錯誤的原因是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中呼叫,執行正常。注意使用了.def檔案,就不需要再使用「extern "c" 」了。

③ 關於呼叫約定

採用②中第二種解決方法,執行,出現錯誤資訊「dll呼叫約定錯誤(error 49)」。

原因是呼叫約定共有5種方式:__fastcall、__pascal、__stdcall、__cdecl及__thiscall(成員函式的呼叫方式,但不能使用它顯示宣告乙個函式),vc++預設呼叫方式為__cdecl,而vb預設呼叫方式則為__stdcall。

解決方法是,更改**如下(指定呼叫方式):

__declspec(dllexport) int __stdcall encrypt(int p, int k);

…多個函式…

int __stdcall encrypt(int p, int k)

④ 源**

cipher.dll:

cipher.cpp內容:

//引入預編譯標頭檔案  __declspec(dllexport)是關鍵

#include 「stdafx.h」

#define cipher_api__declspec(dllexport)//巨集替換功能

//宣告我的函式  

cipher_api int __stdcall encrypt( int p, int k )

………… 多個函式…

以上兩條語句等價於:

__declspec(dllexport) int __stdcall encrypt(int p, int k);

//dll入口函式 (實驗過可選)

bool apientry dllmain(handle hmodule,

dword ul_reason_for_call,

lpvoid lpreserved)

return true;

}//我的函式__stdcall關鍵

int __stdcall encrypt(int p, int k)

…多個函式…

…………………

//我的問題:沒有將.def檔案加入工程,導致生成的dll檔案呼叫函式沒有入口點

cipher.def:

library cipher

exports encrypt

編譯後,將cipher.dll複製到vb程式可執行檔案所在目錄。

也可以在呼叫時輸入乙個完整的路徑。

在vb中呼叫:

option explicit

private declare function encrypt lib 「cipher」 (byval p as long, byval k as long) as long

private sub form_load()

dim c as long

c = encrypt(24, 8)

text1.text = c

end sub

VB呼叫VC DLL的引數問題

問題示例如下,假設vb中申明乙個dll中的匯出函式為 public declare function somefunc lib test.dll alias somefunc byval name as string as long 那麼vc做的dll中的匯出函式原型是什麼?因為vb中的string...

關於C 呼叫VC DLL

由於在c 呼叫vc的dll檔案不能直接引用,那麼,我們可以通過以下辦法解決。dll檔案分為託管和非託管,在呼叫託管的很好辦,直接被使用的需要引用,間接使用的需要拷貝到bin目錄下.非託管的處理會比較麻煩,實際上,你拷貝到bin沒有任何幫助,因為clr會把檔案拷貝到乙個臨時目錄下,然後在那執行web,...

C 呼叫VC dll輸出引數

最近做專案需要把以前vc寫的程式整合到vs2005來,用c 寫的,以前vc的動態連線庫寫好了,重寫比較麻煩,讓c 呼叫vc dll就好了。但碰到了乙個問題 vc中作為輸出引數的char 型別的變數應該怎樣申明才能正確輸出資料呢?一般說來,在vc中一般的輸出引數都為指標或陣列的形式,如果是一般型別的指...