再谈在VB中调用VC++开发的DLL

原创 2004年02月27日 10:15:00

  近日开发一个程序,用到动态链接库,在VB中调用时遇到了一些问题。我查了一些资料,也看了一下CSDN上的文章,感觉这些文章对在VB中调用VC++开发的DLL这一问题阐述得不够详细。因此在我的问题得到解决之余,特为初接触DLL的朋友们写下这篇文章。
   
本文中关于调用约定的解决方法,也适用于解决其它编程语言之间DLL
调用的兼容问题。

关于DLL的创建与调用
  使用VC++的向导即可。具体操作如下:打开菜单“File/New”→选择“Projects/Win32 Dynamic-Link Library”→选择“A simple DLL project”即可。这时系统会自动生成3个文件:*.cppstdafx.cppstdafx.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中调用,运行正常。注意使用了.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)
 
    {
        
int c = p + k;
        
return c;
    
}


源代码
Cipher.dll
 
Cipher.cpp

 
//引入预编译头文件
 
#include
stdafx.h

   #define
CIPHER_API __declspec(dllexport) 

  
//声明我的函数
 
CIPHER_API 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复制到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

转自:http://lanshanlhy.blog.163.com/blog/static/302294762010112832031218/ 再谈在VB中调用VC++开发的DLL  再谈...
  • xl19900502
  • xl19900502
  • 2016年02月22日 11:17
  • 577

VB调用VC++的DLL问题:1.无法返回参数,2.找不到入口点

最近忙于毕业论文的实验,主要用VS2010+openCV做图像处理,做了大量工作,遇到无数的问题。 首先就先说说今天遇到的问题吧:我想利用VB中读取的图像路径传入VC++,之前有的办法一直是将VB的...
  • liuqi19861116
  • liuqi19861116
  • 2012年05月08日 16:50
  • 990

VB中的String类型调用VC的DLL

VB中的String类型调用VC的DLL EXTERN_C BSTR WINAPI RetStr(LPCTSTR str)  {  return SysAllocString((...
  • MARZ07101
  • MARZ07101
  • 2012年10月30日 10:55
  • 2366

解开VC++调用.Net DLL的神秘面纱

这段时间有个项目是需要使用vc++的程序访问.Net的类,在网上搜过很多文章,大致有两个方法: 将.Net程序编译成COM,并让C++代码访问COM组件进行调用。 另一个方法使用CRL编译...
  • lins1393997412
  • lins1393997412
  • 2012年04月08日 07:57
  • 2513

用C#生成.dll 供VB6的开发人员调用

里面有两个方法   Encrypt(string pToEncrypt,string sKey) //加密    Decrypt(string pToDecrypt,string sKey) //解密...
  • xiaoxiaohai123
  • xiaoxiaohai123
  • 2007年12月18日 09:45
  • 1727

在VB和DLL间传递字符串

        用VB调用VC编写的DLL时,必须注意参数的匹配。VC中的变量,都是采用的32位,而VB中的,很多是16位,这就要进行相应的转化。转化的法则很多地方都有。我这里建议大家尽量使用VB,V...
  • sigepluto
  • sigepluto
  • 2007年05月08日 13:56
  • 4781

vc++ 调用外部dll的方法

调用DLL有两种方法:静态调用和动态调用. (一).静态调用其步骤如下: 1.把你的youApp.DLL拷到你目标工程(需调用youApp.DLL的工程)的Debug目录下; 2.把...
  • gaoszzzz
  • gaoszzzz
  • 2017年08月15日 11:09
  • 529

VS2010 VB如何生成DLL文件,调用DLL

一.创建dll文件 1.在vs2010中创建Class Library 项目; 工程名 2.输入代码   3.按F6编译生成Dll文件(\myFirstDll\bin\Debug\myFirstDll...
  • zzuzpb
  • zzuzpb
  • 2013年08月08日 16:51
  • 5218

Delphi中怎么调用vb的DLL

VB直接生成的是ActiveX dll, 经过改造,也能生成标准的Windows DLL。 不知道你说的VB生成的dll是哪一类? 1. 标准的Windows DLL, delphi的例子很多。...
  • km_afei
  • km_afei
  • 2016年12月02日 12:23
  • 335

VB6.0软件调用VS C++ DLL问题解决

源起之前为设备的DLL供客户二次开发,包括C++,C#等调用都没有问题,以一个函数为例,C文件和H文件里写法如下:UCHAR CharToHex(UCHAR ch) extern "C" __decl...
  • yanyuanfen2011
  • yanyuanfen2011
  • 2017年08月14日 20:44
  • 371
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:再谈在VB中调用VC++开发的DLL
举报原因:
原因补充:

(最多只允许输入30个字)