用VB要调用VC6的DLL文件里的多个函数,VC6的DLL应该怎样写?VB又怎样写?能不能说得详细一点!!

 我来答
youhm1
2010-12-13 · TA获得超过115个赞
知道答主
回答量:42
采纳率:0%
帮助的人:65.9万
展开全部
网上 的一篇文章,看完应该对你有所帮助

再谈在VB中调用VC++开发的DLL
作者:未知 来源:月光软件站
近日开发一个程序,用到动态链接库,在VB中调用时遇到了一些问题。我查了一些资料,也看了一下CSDN上的文章,感觉这些文章对在VB中调用VC++开发的DLL这一问题阐述得不够详细。因此在我的问题得到解决之余,特为初接触DLL的朋友们写下这篇文章。

本文中关于调用约 定的解决方法,也适用于解决其它编程语言之间DLL调用的兼容问题。

①关于DLL的创建与调用

使用VC++的向导即可。具体操作如下:打开菜单“File\New”→选择“Projects\Win32 Dynamic-Link Library”→选择“A simple 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”的替换值做更改即可。)

进行了③的更改后,程序又找不到入口点了。再用QuikVie w查看,发现函数名变为“_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)

{

int c = p+k;

return c;

}

④源代码

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

)

{

switch( ul_reason_for_call )

{

case DLL_PROCESS_ATTACH:

case DLL_THREAD_ATTACH:

case DLL_THREAD_DETACH:

case DLL_PROCESS_DETACH:

break;

}

return TRUE;

}

//我的函数

int __stdcall Encrypt ( int p, int k )

{

int c = p + k ;

return c ;

}

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()

Dim c As Long

c = Encrypt(24, 8)

Text1.Text = c

End Sub
littership
2012-07-31 · 超过17用户采纳过TA的回答
知道答主
回答量:49
采纳率:0%
帮助的人:29.2万
展开全部
我也是刚学,所以说下我现在在用的。
首先是用vc些dll,新建一个win32 dynamic-link library空白项目,需要写一个源文件和一个def文件。
先说源文件,就不用写main()了,直接写想要输出的函数,dll内部调用的函数照常写,然后你想要在vb中调用的函数,比如说自己写的一个加法函数和helloworld函数,用add来举例:
int add(int x,int y){
}
就要写成 int _stdcall add(int x,int y){ },要加上_stdcall,否则调用会出错.
然后是写一个def文件。新建个文本文件添加到工程里,后缀要改成.def。然后里面内容这样写:
LIBRARY
EXPORTS
add
helloworld
如果想要改一下函数名,比如改成abc,可以这样
LIBRARY
EXPORTS
abc=add
helloworld
然后输出的函数名就会是abc和helloworld了。
组建一下,会在debug文件夹里发现一个dll文件,如果你的源文件写得没有错的话,那dll这部分就搞定了。
然后到vb调用dll这部分。先把做好的dll,例如mydll.dll,放到vb工程根目录下
首先要声明dll里面的函数。
Private Declare Function add Lib "mydll.dll" (Byval x As long,byval y as long) As Long
注意的点:传递参数如果想要传值,一定要写明byval,因为调用外部函数的默认传递方式是传址。
然后就可以再vb中像使用内部函数一样用add了
dim i,x,y as long
x=1
y=2
i=add(x,y)
又注意,直接在vb里面测试的时候可能会提示“文件未找到 mydll.dll”,不知道是因为我用的是精简版还是什么原因。这个问题在你生成exe文件后,直接运行exe的时候就不会出现了。如果想在vb里直接测试,我的解决方法是把dll的绝对路径写上,即
Private Declare Function add Lib "x:\xxx\xxx\mydll.dll" (Byval x As long,byval y as long) As Long
然后到生成exe的时候再去掉。
如果提示“参数不符”,就检查下自己调用dll里面的函数时参数究竟有没写对。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式