我有VC写的DLL,如何可以在VB中调用,谢谢各位老大了!!! 我有VC写的DLL,如何可以在VB中调用,谢谢各位老大了!!! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 前提是你要了解这个DLL里的过程,然后你就跟调用API的格式一样的调用它的函数就可以了。 在VB中如何调用C++Builder创建的DLL ---- C++Builder具有强大的创建Dynamic Link Library 的能力。许多C++Builderr的书藉在创建使用DLL的章节中直接引用的联机文档中的例子。但在Visual C++和VB中直接调用该示例生成的DLL却出现了一些问题,现在我们结合在VB中的调用给出解决方法。示例代码如下所示: //////////////////////////// Mydll.cpp////////////////////////// double dblValue(double);double halfValue(double);extern __declspec(dllexport) double changeValue(double, bool);double dblValue(double value){ return value * value;};double halfValue(double value){ return value / 2.0;}double changeValue(double value, bool whichOp){ return whichOp ? dblValue(value) :halfValue(value);}---- 对于外部调用函数加入了__declspec(dllexport)修饰成分,这和Visual C++是相同的,说明该函数将自动从DLL中导出,并对任何调用程序可用。然后,对上述代码在C++Builder环境中编译链接生成Mydll.DLL和Mydll.Lib,并将Mydll.DLL拷入Windows\system目录下(由于VB默认的查找DLL的目录为Windows\system)。 ---- 在VB5.0中新建一个应用,并添加一个模块,在模块中将函数调用说明如下: Declare Function changeValue Lib "mydll" (ByVal Value As Double, ByVal WhichOp AsBoolean) As Double---- 然后在窗体的一个按钮的Click事件中调用changeValue,对该函数进行测试。测试代码如下: Dim aa As Double aa = changeValue(10,True)---- 实际运行中出现了“找不到DLL入口点changeValue in MyDll”的错误信息。 ---- 这时利用资源管理中的快速查看功能查看Mydll.DLL,在Export Table中有关信息如下: Ordinal EntryPoint Name 0000 00013c4 @changeValue$qd4bool---- 发现changeValue函数除了函数名外之外前后还有@、$等附加字符。查阅有关资料得知这是由于编译器对C++名字的修整造成的,由于Microsoft的Visual C++和Borland的C++ Builder的修整方式不同,在分别修整C++名字的时候,对于相同的函数当然就不会出现相同的名字。好再C++语言通过从系统内定义的函数和对象中删除修整,从而有效地解决这一问题。 ---- 将语句extern “C” 放置在程序中的代码块内,编译器就将不会修整这块代码。这时将Mydll.cpp有关代码修改如下: extern “C” __declspec(dllexport)double changeValue(double, bool);---- 再次查看重新生成的Mydll.DLL,这时Export table中的有关信息如下: Ordinal EntryPoint Name 0000 00013c4 _changeValue---- @、$等字符没有了,但在函数名多了一条”_”线。将Mydll.DLL重新拷入windows\system目录下,并在VB的模块中修改调用说明如下: Declare Function changeValue Lib "mydll" Alias “_changeValue” (ByVal Value As Double,ByVal WhichOp As Boolean) As Double---- 运行VB测试程序,出现”DLL 调用约定错误”的错误提示信息。说明changeValue找到了,只是调用约定不对。我们知道调用约定有__fastcall、__pascal、__stdcall、__cdecl四种方式,而在C++Builder中默认调用约定为__cdecl方式,而VB中调用约定为__stdcall方式。 ---- 再将Mydll.cpp的代码修改如下: extern “C”__declspec(dllexport)double __stdcall changeValue(double, bool);……double __stdcall changeValue(double value, bool whichOp){ return whichOp ? dblValue(value) :halfValue(value);}……---- 这时查看重新编译链接生成的Mydll.DLL,Export table中的有关信息如下: Ordinal EntryPoint Name 0000 00013c4 changeValue---- 发现函数名前的“_”线也没有,再次修改VB中调用说明如下: Declare Function changeValue Lib "mydll" (ByVal Value As Double, ByVal WhichOp As Boolean) As Double---- 运行测试程序,运行结果正确。 ---- 后又将__stdcall调用约定方式改__pascal调用约定方式,运行结果同样正确,但改为__fastcall调用约定方式不行。 ---- 上面所讨论的解决方法不仅适用VB,该方法同样适样Visual C++,这样使Visual C++和C++ Builder 不同编译器生成的DLL可以互相兼容。 呵呵,我昨天在写完的时候,已经找过了.当然之所以没弄出来,完全是我的错,居然在VB中把声明的函数名弄错了,气得我就差背气了.不过,还是感谢上面几位.我本想结帖.但突然又想弄明白一件事.为什么我在写动态库的时候,这样定义函数也可以通过编译,这个位置我就搞不清楚.extern "C" __declspec(dllexport) int __stdcall MyFunction(....)extern "C" __declspec(dllexport) __stdcall int MyFunction(....)这两种情况都一样,但调用的时候,后一种对应的声明也要变,我想问一下,这个顺序有什么特别的意义吗?? 多谢各位了. 这段VBS代码有什么问题? 请高手帮忙,关于两个access数据库之间的数据插入问题。 如何打开或关闭windows声音?在线等 请教既懂VB6又懂VC6并且对DLL十分熟悉的高手(200分火急) vb遍历进程 IUnknown ??? 超级简单(我就是找不到错)标准表达式中数据类型不匹配。"?? 求问:如何在VB下接收UDP的分组广播报文? 如何学习VB? 我想做一个多媒体播放器,请大家给些idea。 请教! 连接上一个数据库后,怎样知道数据库里包含哪些表?
---- C++Builder具有强大的创建Dynamic Link Library 的能力。许多C++Builderr的书藉在创建使用DLL的章节中直接引用的联机文档中的例子。但在Visual C++和VB中直接调用该示例生成的DLL却出现了一些问题,现在我们结合在VB中的调用给出解决方法。示例代码如下所示: //////////////////////////
// Mydll.cpp
//////////////////////////
double dblValue(double);
double halfValue(double);
extern __declspec(dllexport)
double changeValue(double, bool);double dblValue(double value)
{
return value * value;
};double halfValue(double value)
{
return value / 2.0;
}double changeValue(double value, bool whichOp)
{
return whichOp ? dblValue(value) :
halfValue(value);}---- 对于外部调用函数加入了__declspec(dllexport)修饰成分,这和Visual C++是相同的,说明该函数将自动从DLL中导出,并对任何调用程序可用。然后,对上述代码在C++Builder环境中编译链接生成Mydll.DLL和Mydll.Lib,并将Mydll.DLL拷入Windows\system目录下(由于VB默认的查找DLL的目录为Windows\system)。
---- 在VB5.0中新建一个应用,并添加一个模块,在模块中将函数调用说明如下: Declare Function changeValue Lib "mydll"
(ByVal Value As Double, ByVal WhichOp As
Boolean) As Double---- 然后在窗体的一个按钮的Click事件中调用changeValue,对该函数进行测试。测试代码如下:
Dim aa As Double
aa = changeValue(10,True)---- 实际运行中出现了“找不到DLL入口点changeValue in MyDll”的错误信息。
---- 这时利用资源管理中的快速查看功能查看Mydll.DLL,在Export Table中有关信息如下: Ordinal EntryPoint Name
0000 00013c4 @changeValue$qd4bool---- 发现changeValue函数除了函数名外之外前后还有@、$等附加字符。查阅有关资料得知这是由于编译器对C++名字的修整造成的,由于Microsoft的Visual C++和Borland的C++ Builder的修整方式不同,在分别修整C++名字的时候,对于相同的函数当然就不会出现相同的名字。好再C++语言通过从系统内定义的函数和对象中删除修整,从而有效地解决这一问题。
---- 将语句extern “C” 放置在程序中的代码块内,编译器就将不会修整这块代码。这时将Mydll.cpp有关代码修改如下: extern “C” __declspec(dllexport)
double changeValue(double, bool);---- 再次查看重新生成的Mydll.DLL,这时Export table中的有关信息如下:
Ordinal EntryPoint Name
0000 00013c4 _changeValue---- @、$等字符没有了,但在函数名多了一条”_”线。将Mydll.DLL重新拷入windows\system目录下,并在VB的模块中修改调用说明如下:
Declare Function changeValue Lib "mydll"
Alias “_changeValue” (ByVal Value As Double,
ByVal WhichOp As Boolean) As Double---- 运行VB测试程序,出现”DLL 调用约定错误”的错误提示信息。说明changeValue找到了,只是调用约定不对。我们知道调用约定有__fastcall、__pascal、__stdcall、__cdecl四种方式,而在C++Builder中默认调用约定为__cdecl方式,而VB中调用约定为__stdcall方式。
---- 再将Mydll.cpp的代码修改如下: extern “C”__declspec(dllexport)
double __stdcall changeValue(double, bool);……
double __stdcall changeValue(double value,
bool whichOp)
{
return whichOp ? dblValue(value) :
halfValue(value);}
……---- 这时查看重新编译链接生成的Mydll.DLL,Export table中的有关信息如下:
Ordinal EntryPoint Name
0000 00013c4 changeValue---- 发现函数名前的“_”线也没有,再次修改VB中调用说明如下:
Declare Function changeValue Lib "mydll"
(ByVal Value As Double, ByVal WhichOp
As Boolean) As Double---- 运行测试程序,运行结果正确。
---- 后又将__stdcall调用约定方式改__pascal调用约定方式,运行结果同样正确,但改为__fastcall调用约定方式不行。 ---- 上面所讨论的解决方法不仅适用VB,该方法同样适样Visual C++,这样使Visual C++和C++ Builder 不同编译器生成的DLL可以互相兼容。
为什么我在写动态库的时候,这样定义函数也可以通过编译,这个位置我就搞不清楚.
extern "C" __declspec(dllexport) int __stdcall MyFunction(....)
extern "C" __declspec(dllexport) __stdcall int MyFunction(....)
这两种情况都一样,但调用的时候,后一种对应的声明也要变,我想问一下,这个顺序有什么特别的意义吗?? 多谢各位了.