日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

使用VC编写VB使用DLL

發(fā)布時(shí)間:2025/3/20 c/c++ 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用VC编写VB使用DLL 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

使用VC編寫VB使用DLL

一、在函數(shù)定義前必須加上extern "c",_stdcall關(guān)鍵字。
?extern "C" int _stdcall Sum(int x,int y)
?{
??return x+y;
?}
?
二、DLL的.def文件中必須加上入口函數(shù)
??? EXPORTS
???? sample @1
????
?sample是你要在VB中調(diào)用的函數(shù)名,@1表示該函數(shù)在DLL中的編號(hào)
?
三、要注意DLL中的函數(shù)和VB中的函數(shù)聲明在名稱、返回類型、參數(shù)類型、參數(shù)個(gè)數(shù)等方面必須完全相同,尤其要注意大小寫的問題。

注意事項(xiàng):
?1、必須保證VB和VC的參數(shù)個(gè)數(shù)相同,參數(shù)所占字節(jié)數(shù)也一致

3.數(shù)組參數(shù)在DLL中的傳遞
  由于DLL經(jīng)常用來進(jìn)行一些底層的運(yùn)算操作,因此應(yīng)用程序常需要傳遞大量的數(shù)據(jù)給DLL。在C++中,指針是進(jìn)行數(shù)組操作的最佳選擇,但VB中沒有指針的概念。這通常可用兩種方法來解決。
  其一,在VB中聲明DLL時(shí),用byref來代替byval,即可將數(shù)組指針傳遞給DLL。
  另外,將數(shù)組聲明為變體型(variant),即可直接將數(shù)組傳遞給DLL。

四、在vb中聲明("dllTest.dll" 使用的是相對(duì)路徑,你可以將dll.dll放到.exe所在的目錄或系統(tǒng)目錄),函數(shù)名大小敏感

Private Declare Function Sum Lib "dllTest.dll" (ByVal x As Long, ByVal y As Long) As Long

五、例子
?1、新建一個(gè)win32 dynamic library,空的工程
?2、新建一個(gè)dllTest.cpp 文件,并添加到工程。內(nèi)容如下
// dll4.cpp : Defines the entry point for the DLL application. //#include "stdafx.h"BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {return TRUE; }extern "C" int _stdcall Sum(int x,int y) {return x+y; } extern "C" int _stdcall GetNum(int Num) /*具體實(shí)現(xiàn)*/ { return Num; }

?// dll4.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"

BOOL APIENTRY DllMain( HANDLE hModule,
?????????????????????? DWORD? ul_reason_for_call,
?????????????????????? LPVOID lpReserved
????? )
{
??? return TRUE;
}

extern "C" int _stdcall Sum(int x,int y)
{
?return x+y;
}
extern "C" int _stdcall GetNum(int Num)????? /*具體實(shí)現(xiàn)*/
{
?return Num;????
}

?3,新建一個(gè)dllTest.def文件,并添加到工程。內(nèi)容如下:
?EXPORTS???
?????? ? Sum @1?
?
?
?相關(guān)知識(shí)點(diǎn):
?
?1)? 函數(shù)調(diào)用約定(Calling Convention)
??
?c++編譯器
?
??? 編譯器的命令行參數(shù)是/Gz,__stdcall是Pascal程序的缺省調(diào)用方式,大多數(shù)Windows的API也是__stdcall調(diào)用約定。__stdcall函數(shù)調(diào)用約定將函數(shù)參數(shù)從右向左入棧,除非使用指針或引用類型的參數(shù),所有參數(shù)采用傳值方式傳遞,由被調(diào)用函數(shù)負(fù)責(zé)清除棧中的參數(shù)。對(duì)于C函數(shù),__stdcall的名稱修飾方式是在函數(shù)名字前添加下劃線,在函數(shù)名字后添加@和函數(shù)參數(shù)的大小,例如:_functionname@number
?函數(shù)名字修飾(Decorated Name)方式

??? 函數(shù)的名字修飾(Decorated Name)就是編譯器在編譯期間創(chuàng)建的一個(gè)字符串,用來指明函數(shù)的定義或原型。LINK程序或其他工具有時(shí)需要指定函數(shù)的名字修飾來定位函數(shù)的正確位置。多數(shù)情況下程序員并不需要知道函數(shù)的名字修飾,LINK程序或其他工具會(huì)自動(dòng)區(qū)分他們。當(dāng)然,在某些情況下需要指定函數(shù)的名字修飾,例如在C++程序中,為了讓LINK程序或其他工具能夠匹配到正確的函數(shù)名字,就必須為重載函數(shù)和一些特殊的函數(shù)(如構(gòu)造函數(shù)和析構(gòu)函數(shù))指定名字裝飾。另一種需要指定函數(shù)的名字修飾的情況是在匯編程序中調(diào)用C或C++的函數(shù)。如果函數(shù)名字,調(diào)用約定,返回值類型或函數(shù)參數(shù)有任何改變,原來的名字修飾就不再有效,必須指定新的名字修飾。C和C++程序的函數(shù)在內(nèi)部使用不同的名字修飾方式,下面將分別介紹這兩種方式。

1. C編譯器的函數(shù)名修飾規(guī)則

??? 對(duì)于__stdcall調(diào)用約定,編譯器和鏈接器會(huì)在輸出函數(shù)名前加上一個(gè)下劃線前綴,函數(shù)名后面加上一個(gè)“@”符號(hào)和其參數(shù)的字節(jié)數(shù),例如_functionname@number。__cdecl調(diào)用約定僅在輸出函數(shù)名前加上一個(gè)下劃線前綴,例如_functionname。__fastcall調(diào)用約定在輸出函數(shù)名前加上一個(gè)“@”符號(hào),后面也是一個(gè)“@”符號(hào)和其參數(shù)的字節(jié)數(shù),例如@functionname@number。???
?
2. C++編譯器的函數(shù)名修飾規(guī)則

??? C++的函數(shù)名修飾規(guī)則有些復(fù)雜,但是信息更充分,通過分析修飾名不僅能夠知道函數(shù)的調(diào)用方式,返回值類型,參數(shù)個(gè)數(shù)甚至參數(shù)類型。不管__cdecl,__fastcall還是__stdcall調(diào)用方式,函數(shù)修飾都是以一個(gè)“?”開始,后面緊跟函數(shù)的名字,再后面是參數(shù)表的開始標(biāo)識(shí)和按照參數(shù)類型代號(hào)拼出的參數(shù)表。對(duì)于__stdcall方式,參數(shù)表的開始標(biāo)識(shí)是“@@YG”,對(duì)于__cdecl方式則是“@@YA”,對(duì)于__fastcall方式則是“@@YI”。參數(shù)表的拼寫代號(hào)如下所示:
X--void???
D--char???
E--unsigned char???
F--short???
H--int???
I--unsigned int???
J--long???
K--unsigned long(DWORD)
M--float???
N--double???
_N--bool
U--struct
....
指針的方式有些特別,用PA表示指針,用PB表示const類型的指針。后面的代號(hào)表明指針類型,如果相同類型的指針連續(xù)出現(xiàn),以“0”代替,一個(gè)“0”代表一次重復(fù)。U表示結(jié)構(gòu)類型,通常后跟結(jié)構(gòu)體的類型名,用“@@”表示結(jié)構(gòu)類型名的結(jié)束。函數(shù)的返回值不作特殊處理,它的描述方式和函數(shù)參數(shù)一樣,緊跟著參數(shù)表的開始標(biāo)志,也就是說,函數(shù)參數(shù)表的第一項(xiàng)實(shí)際上是表示函數(shù)的返回值類型。參數(shù)表后以“@Z”標(biāo)識(shí)整個(gè)名字的結(jié)束,如果該函數(shù)無參數(shù),則以“Z”標(biāo)識(shí)結(jié)束。下面舉兩個(gè)例子,假如有以下函數(shù)聲明:


int Function1(char *var1,unsigned long);
其函數(shù)修飾名為“?Function1@@YGHPADK@Z”,而對(duì)于函數(shù)聲明:
void Function2();
?其函數(shù)修飾名則為“?Function2@@YGXXZ” 。
?

??? 對(duì)于C++的類成員函數(shù)(其調(diào)用方式是thiscall),函數(shù)的名字修飾與非成員的C++函數(shù)稍有不同,首先就是在函數(shù)名字和參數(shù)表之間插入以“@”字符引導(dǎo)的類名;其次是參數(shù)表的開始標(biāo)識(shí)不同,公有(public)成員函數(shù)的標(biāo)識(shí)是“@@QAE”,保護(hù)(protected)成員函數(shù)的標(biāo)識(shí)是“@@IAE”,私有(private)成員函數(shù)的標(biāo)識(shí)是“@@AAE”,如果函數(shù)聲明使用了const關(guān)鍵字,則相應(yīng)的標(biāo)識(shí)應(yīng)分別為“@@QBE”,“@@IBE”和“@@ABE”。如果參數(shù)類型是類實(shí)例的引用,則使用“AAV1”,對(duì)于const類型的引用,則使用“ABV1”。下面就以類CTest為例說明C++成員函數(shù)的名字修飾規(guī)則:


class CTest
{
......
private:
??? void Function(int);
protected:
??? void CopyInfo(const CTest &src);
public:
??? long DrawText(HDC hdc, long pos, const TCHAR* text, RGBQUAD color, BYTE bUnder, bool bSet);
??? long InsightClass(DWORD dwClass) const;
......
};
?

?

總結(jié)

以上是生活随笔為你收集整理的使用VC编写VB使用DLL的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。