您的当前位置:首页正文

分享如何在VB中调用VC编写的DLL

2023-10-07 来源:爱站旅游
导读分享如何在VB中调用VC编写的DLL
分享如何在VB中调⽤VC编写的DLL

⼀般来说,VB和VC共同编程有3种⽅式:⼀种是VC⽣成DLL,在VB中调⽤DLL;⼀种是VC⽣成ActiveX控件(.ocx),在VB中插⼊;还有⼀种是在VC中⽣成ActiveX Automation服务器,在VB中调⽤。相对⽽⾔,第⼀种⽅法对VC编程者的要求最低,但要求你的伙伴进⾏配合,我推荐这种⽅法。

先说说VC++的编程。⾸先在VC++中⽣成Win32 DLL⼯程。在这个⼯程中添加⼏个函数供VB⽤户调⽤。⼀个DLL中的函数要想被VB调⽤,必须满⾜两个条件:⼀是调⽤⽅式为stdcall,另⼀个是必须是export的。要做到第⼀条,只须在函数声明前加上__stdcall关键字。如:

short __stdcall sample(short nLen, short *buffer) 要做到第⼆条,需要在*.def⽂件中加上如下的⼏⾏:

EXPORTS sample @1

这⾥的sample是你要在VB中调⽤的函数名,@1表⽰该函数在DLL中的编号,每个函数都不⼀样。注意这⾥的函数名是区分⼤⼩写的。⾄于你说的需要传递⼤量数据,可以这样做,在VB中⽤⼀个数组存放数据,然后将该数组的⼤⼩和地址传给VC(⾄于如何在VB中编程我会在下⾯介绍)。就象上⾯的例⼦,nLen是数组⼤⼩,buffer是数组地址,有了这两条,你可以象使⽤VC的数组⼀样进⾏处理了。⾄于输出图形,可以⽣成WMF或BMP格式,让VB调⽤。不过,我认为也可以直接输出到视窗,只要VB将窗⼝的句柄hWnd和hDC以及视窗的绘图位置(VB和VC采⽤的坐标系必须⼀致才⾏)传给VC就⾏了。⽽VB的AutoRedraw属性必须为False,在Paint事件中调⽤VC的绘图程序。

再谈谈VB的编程。VB调⽤DLL的⽅法和调⽤Windows API的⽅法是⼀样的,⼀般在VB的书中有介绍。对于上⾯⼀个例⼦,先要声明VC函数:

Declare Function sample Lib \"mydll.dll\" (ByVal nLen As Integer, buffer As Integer) As Integer

这⾥mydll.dll是你的dll的名字。你可能已经注意到了两个参数的声明有所不同,第⼀个参数加上了ByVal。规则是这样的:如果在VC中某个参数声明为指针和数组,就不加ByVal,否则都要加上ByVal。在VB中调⽤这个函数采⽤这样的语法: sample 10, a(0)

这⾥的a()数组是⽤来存放数据的,10为数组长度,这⾥的第⼆个参数不能是a(),⽽必须是要传递的数据中的第⼀个。这是VB编程的关键。

下⾯在说⼏个可能遇到的问题。⼀个问题是VB可能报告找不到dll,你可以把dll放到system⽬录下,并确保VB的Declare语句正确。另⼀个问题是VB报告找不到需要的函数,这通常是因为在VC中*.def⽂件没设置。第三种情况是VB告诉不能进⾏转换,这可能是在VC中没有加上__stdcall关键字,也可能是VB和VC的参数类型不⼀致,注意在VC中int是4个字节(相当于VB的Long),⽽VB的Integer只有2个字节。必须保证VB和VC的参数个数相同,所占字节数也⼀致。最后⼀个要注意的问题是VC中绝对不能出现数组越界的情况,否则会导致VB程序崩溃

  动态链接库(DLL)作为Windows操作系统的基础,具有优越的应⽤性能:

  DLL扩展了应⽤程序的特性。由于DLL能够动态地装⼊进程的地址空间,因此应⽤程序能够在运⾏时确定需要执⾏什么操作,然后装⼊相应的代码,以便根据需要执⾏这些操作。

  DLL可以⽤多种语⾔进⾏编写。例如⽤VB来编写应⽤程序的界⾯,⽽⽤C++来编写诸如算法、通讯之类的底层操作。  DLL简化了软件项⽬的管理。如果在软件开发过程中不同的⼯作⼩组在不同的模块上⼯作,那么这个项⽬管理起来⽐较容易。

  DLL有助于节省内存。如果两个或多个应⽤程序使⽤同⼀个DLL,那么该DLL的页⾯只要放⼊RAM⼀次,所有的应⽤程序都可以共享它的各个页⾯。

  DLL有助于资源的共享。DLL可以包含对话框模板、字符串、图标和位图等资源,多个应⽤程序能够使⽤DLL来共享这些资源。

  DLL有助于应⽤程序的本地化。例如,只包含代码⽽不包含⽤户界⾯组件的应⽤程序可以加载包含本地化⽤户界⾯组件的DLL 。

  DLL有助于解决平台差异。不同版本的Windows配有不同的函数,开发⼈员常常想要调⽤新的函数。但是,如果源代码包含了对⼀个新函数的调⽤,⽽应⽤程序将要在不能提供该函数的Windows版本上运⾏,那么操作系统的加载程序将拒绝运⾏该进程。如果将这些新函数保存在DLL中,那么应⽤程序就能够将它们加载到Windows的⽼版本上,就可以成功地调⽤该函数。

  初次接触DLL的⽤户经常会遇到⼀个问题:在VC环境下创建的DLL,在VC⾥运⾏的好好的,可在VB应⽤程序中调⽤时却⽼是出现\"调⽤约定错误\"、\"找不到⼊⼝点\"之类的错误。这主要是由以下疏漏造成的。

  ⾸先,要注意DLL中的函数和VB中的函数声明在名称、返回类型、参数类型、参数个数等⽅⾯必须完全相同,尤其要注意⼤⼩写的问题。

  其次,在DLL的.def⽂件中必须加上⼊⼝函数。

  最后,在函数定义前必须加上extern \"c\",_stdcall关键字。  具体格式可参看应⽤实例。

  由于DLL经常⽤来进⾏⼀些底层的运算操作,因此应⽤程序常需要传递⼤量的数据给DLL。在C++中,指针是进⾏数组操

作的最佳选择,但VB中没有指针的概念。这通常可⽤两种⽅法来解决。

  其⼀,在VB中声明DLL时,⽤byref来代替byval,即可将数组指针传递给DLL。  另外,将数组声明为变体型(variant),即可直接将数组传递给DLL。

  以下通过⼀具体实例来说明在VB中调⽤VC环境下创建的DLL的过程。

  创建⼀⽤于信号处理的DLL,\"SigPro.dll\",其中有⼀个⽤于富⽒计算的函数\"Fourier\"。VC中的声明:

在\"SigPro.h\"中加⼊以下代码,复制代码 代码如下:

extern \"C\"{

double EXPORT _stdcall Fourier(long int *Sample,int NumSam,int OvertoneOrder,bool SinOrCos);}

在\"SigPro.cpp\"中加⼊以下代码,extern \"C\"

double EXPORT _stdcall Fourier(long int *Sample,int NumSam,int OvertoneOrder,bool SinOrCos){int i;

double result=0.0;

if(SinOrCos==true){

for(i=0;iresult=result+*(Sample+i)*cos(OvertoneOrder*i*2*3.1415926/NumSam);}}else{

for(i=0;iresult=result+*(Sample+i)*sin(OvertoneOrder*i*2*3.1415926/NumSam);}}

result =result*2/NumSam;return result;}

在\"SigPro.def\"中加⼊以下代码,  EXPORTS  Fourier

VB中的调⽤声明:

  Public Declare Function Fourier Lib \"SigPro\" (ByRef Sample() As Long, ByVal NumSam As Integer, ByValOvertoneOrder As Integer, ByVal SinOrCos As Boolean) As Double

因篇幅问题不能全部显示,请点此查看更多更全内容