说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

VB调用C程序动态链接库的方法

HTML文档下载 WORD文档下载 PDF文档下载
VB调用C程序动态链接库的方法
摘 要
文中介绍了一种实现VB调用C语言程序的方法-动态连接库法,给出了动态链接库制作的一般框架,通过实例描述了动态连接库的实现及其制做方法、编程步骤,这种方法具有普遍的意义。
关键词: VB,动态连接库DLL,C程序

一、引言

Visual Basic( 以下简称VB)是一种可视化的面向对象的编程语言,以其编程简单、快捷等特点,深受广大WINDOWS程序员的青睐。利用VB开发界面友好、操作方便的软件只需很短的时间。但是VB运行速度较慢,对于庞大的科学计算问题,VB的这种慢速会使人难以忍受。C语言是国际上非常流行的一种中级编程语言,以其灵活、高效等优点而获得广泛应用,许多的应用程序都是用C语言在DOS环境下编写而成。那么如何发挥VB和C这两种语言的优势,用VB设计一种良好的for windows界面来调用C语言程序,即实现VB调用C语言程序呢?现有的文献只提到动态链接库(以下简称DLL)可以将这两种语言连接起来,但没有讲动态链接库DLL的制做及其编程方法。本文详细介绍了Borland C环境下制作动态链接库以及VB调用for dos动态链接库的的方法、步骤,并通过实例描述VB调用C程序的全过程。

二、用Borland C编写DLL程序的方法

要想实现VB调用C程序,首先需要用Borland C编写动态连接库DLL程序(假设DLL程序取名为example)。动态链接库包含四个文件:C语言源程序(.C)、模块定义文件(.DEF)、原型函数文件(.H)和工程文件(.PRJ)。下面分别详细介绍一下这四种文件的具体结构。
1、编写C语言源程序的框架:
C语言源程序(example.C),它包括三种函数:入口函数、输出函数和终止函数。其具体结构如下:
/*************************************/
/* 文件名: example.C */
/*************************************/
#include
/***********入口函数***********/
int FAR PASCAL LibMain ( HANDLE hInstance,
WORD wDataSeg,
WORD cbHeapSize,
LPSTR lpszCmdLine )
{
if (cbHeapSize!=0)
UnlockData(0);
return (1);
}

/***********输出函数***********/

int FAR PASCAL example(int param1,...,char param n)
{
...... /*C语言应用程序*/
}
/***********终止函数***********/
int FAR PASCAL WEP ( int /*SystemExit*/ )
{
return(1);
}
以上各组成部分参数的含义:Windows.h头文件,它包含有数据类型的定义、API入口点定义和其它有用的参数信息。PASCAL说明符定义该程序的传递参数和净化堆栈的协定(注意:DLL外部传送的指针必须是远指针FAR)。LibMain带四个参数:
hInstance、 wDataSeg、cbHeapSize和lpszCmdLine。第一个参数hInstance是DLL事例句柄, wDataSeg参数是数据段(DS)寄存器值,cbHeapSize参数是在模块定义文件中定义的堆的大小,LibMain 使用该值使本地堆初始化。lpszCmdLine参数包括命令行信息,但很少被DLL使用。一般来说,这四个参数是制作DLL通用的参数。
如果不想让DLL数据被封住,那么必须调用unlockdata恢复正常的非锁状态,如果DLL初始化已经成功,DLL则返回1,若不成功则返回0值,且 DLL退出系统。
DLL的输出函数实现用户所要完成的任务,这部分是DLL的核心。它与一般C语言程序不同之处在于无scanf函数。所有的外部指针都是远指针FAR。画直线函数要用lineto函数。
DLL包括一个终止函数,终止函数有时称为退出函数,它的名字必须是WEP。且它可以被包括在DLL模块定义文件的EXPORTS段中。
2、模块定义文件(.DEF)的结构和各段的意义
模块定义文件的结构如下:
/*************************************/
/* 文件名: example.DEF */
/*************************************/
LIBRARY example /* DLLname */
DESCRIPTION ' example.DLL'
EXETYPE WINDOWS
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE SINGLE
HEAPSIZE 1024
EXPORTS
example @1
WEP @2
关键字LIBRARY是把这个模块视为一个DLL,库的名字example跟在其后,且必须与该库的名字、DEF中的DLL的文件名相一致。DESCRIPTION语句采用一个字符串,其长度可达128个字符,通常用它来保存模块描述的信息。EXETYPE windows语句每个windows应用程序和DLL都需要。DATA语句定义该库数据段的内存属性,关键字MOVEABLE允许内存管理程序在必要时移动内存段,关键字SINGLE是DLL必要,因为DLL总是有一个单一数据段,而不管访问它的应用程序的数量。HEAPSIZE语句用来定义一个DLL局部堆的初始规模,执行局部内存分配的DLL必须在库启动时使该堆初始化,堆的大小被传送给DLL的LiEntry的程序。然后用该堆的大小调用Locallnit使DLL的局部堆初始化。
EXEPORTS语句定义将被用作来自应用程序或来自其它DLL入口点的程序,windows利用这个信息建立一个序数入口值,序数入口值是一个优化的值,允许动态连接机制更快块操作且使用较少的内存。
一般来说,模块定义文件(.DEF)的结构除取动态库的名字不同外,其它结构都是固定的。
3.建立原形函数文件(.H)
原形函数的功能是进一步声明调用函数的函数名和传递的参数,其形式为:
/*************************************/
/* 文件名: example.H */
/*************************************/
extern "C" int _export FAR PASCAL example(int param1,...,char param n) ;
4.建立工程文件(.PRJ)
工程文件中包含有example.C、example.DEF两个文件后,然后编译连接生成动态链接库即可。
以上是制作动态连接库的框架,现在通过一个实例介绍制作动态链接库的方法。如要求程序完成功能为:打开一个数据文件读出前两个数据,将这两个数与所传递的两个参数相加,返回它们的和。设该DLL程序的名字为ADD。
第一步:在Borland C++环境下编辑.C文件、.DEF文件和.H文件,并建立.PRJ文件。如
(1)编写C语言源程序清单:
/*************************************/
/* 文件名: ADD.C */
/*************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include "c:\ADD.h"
/*入口函数*/
int FAR PASCAL LibMain (HANDLE hInstance ,
WORD wDataSeg ,
WORD cbHeapSize,
LPSTR lpszCmdLine )
{
if (cbHeapSize!=0)
UnlockData(0);
return 1;
}
/*输出函数*/
int FAR PASCAL ADD(int x,int y,char *filein)
{ int a,b;
fp=fopen(filein,"r");
if(fp==NULL) { exit(0);}
int temp1=0,temp2=0;
fscanf(fp,"%d",&a);
fscanf(fp,"%d",&b);
temp1=x+a;
temp2=y+b;
temp1=temp1+temp2;
fclose(fp);
return(temp1);
}
/*退出函数*/
int FAR PASCAL WEP ( int/*SystemExit*/ )
{
return(1);
}
2)ADD.DEF文件的程序清单:
/*************************************/
/* 文件名: ADD.H */
/*************************************/
LIBRARY ADD
DESCRIPTION 'ADD.DLL'
EXETYPE WINDOWS
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE SINGLE
HEAPSIZE 1024
EXPORTS
ADD @1
WEP @2
(3)ADD.H程序清单:
/*************************************/
/* 文件名: ADD.H */
/*************************************/
extern "C" int _export FAR PASCAL add(int x,int y,char *filein) ;
(4)建立工程文件:
在Borland C++环境下的project项中打开open project file项并建立ADD.prj,在add
item中加入ADD.C文件和ADD.DEF文件即可建立工程文件。
第二步,在Borland C的options项的Applation中选择Windows DLL,再在Compile中选择Build all,这样就可生成动态链接库ADD.DLL供VB调用。

三、VB3.0调用动态链接库DLL方法

制作好DLL之后,就可以用VB调用它,实现VB调用C程序。VB程序要使用DLL中的函数,首先必须要有特殊的声明,用Declare声明语句在窗体级或模块级或全局模块的代码声明段进行声明,将动态链接库中的函数声明到VB中,供VB程序调用。
语句格式为:Declare Sub 过程名Lib [ Alias " 别名]([ByVal 参数AS类型]),或为Declare Function函数名Lib [Alias " 别名]([ByVal 参数AS类型])AS类型在声明中首先用Declare关键字表示声明DLL中的函数。在C语言中有的函数类型为VOID,它表示不具有返回值,则必须用关键字Sub将其声明成过程。有的函数具有返回值,则必须用关键字Function将其声明成函数,并且在声明语句的最后要用AS关键字指明函数返回值的类型。
例如上面的ADD.DLL在VB中就可以声明为:
Declare Function ADD Lib c:\ADD.dll―ByVal X AS Integer, ByVal Y AS Integer ,ByVal filein as
string)AS Integer
通过此声明语句将函数ADD声明到VB中,便可直接调用。

四、结束语

以上详细介绍了Borland C环境下制作动态链接库以及VB调用for dos动态链接库的方法、步骤,并通过实例说明VB调用C语言程序的方法。举例程序ADD经VB3.0编译,在486微机上调试通过。本文介绍的方法具有广泛的意义,也完全适用于C++ 语言程序。

招聘iOS开发,老板必问的5个问题 护航科技吴伟湘:IT离线安全体检服务将带来颠覆 百度王继平:移动互联网时代云平台思路 “第八届开源中国开源世界高峰论坛”火热开启 微软发布SQL Server 2014预览版,展示内存数据库技术 帮助软件开发者提高效率的10个小窍门 我想做个程序员:Technovation Challenge圆女孩编程梦想 未来我们开发的Google Glass应用将会是什么样? 独家:前RIM大中华区总经理刘征宇,加入Appconomy 用一个API搞定一切 Segment.io为移动开发者提供便利的分析数据分发服务 TIOBE 6月编程语言排行榜:JavaScript回归前十 《Kingdom Rush Frontiers》上线后 迅速抢占27个国家游戏榜首 移动周报:85后程序员,iOS开源项目,细数7天大事件! Instagram:从Redis到Cassandra 成本节省1/4 乐元素CTO凌聪访谈:游戏引擎技术选型之王道 iOS 7的新设计并非止于外表 WWDC 2013大会10大启示:正向开发者支付大量现金 云计算大会微软专场成功举办 Windows Azure公众预览版上线 IBM全球大裁员 在美国裁员已经开始 动动鼠标,决定“中国十大优秀开源项目”的归属 为改善Flickr 雅虎收购拍照应用开发商GhostBird 让你轻松学习新代码库的六个步骤 RESTful API 设计最佳实践 谷歌11亿美元豪购Waze原因:获取数据 争本地广告市场 为什么大家都要疯狂吐槽iOS 7的扁平化设计? 伟大的程序员是天生的,不是造就的 比Hive高效7倍 Facebook推新一代查询引擎Presto 未来的存储系统设计——PMC技术交流会举行 第五届中国云计算大会PPT尝鲜:十位专家分享的架构实践 “DIY”可穿戴设备:索尼开放智能手表固件 在微软的八个月里,我学到了这些 这个美元符号是什么意思? to:asia(),hushuo,seesea,inside1以及各位大虾,可以再给小女子讲一下指针的问题吗? win 2k pro 如何查看有哪些人联着我的机子?就跟98的网络资源管理中的一样。 十万火急!!TADOTable的lookup类型的新字段不能用于Sort吗?搞定了立即给分!! CListCtrl控件問題 怎么我在VC++6.0中的窗口属性中设一些属性好像没用一样??? 三台机器不用HUB如何实现互相访问? 请教通讯的问题 用accsee数据库 怎么不显示登陆的用户密码框? c,如何得到一个文件名中指定位置指定长度的字符串?? 服务器是否打开支持FileSystemObject对象的权限 我的数据表列宽为7个字符 , 而我只输入3个字符 , 当我输入4个字符后 , 再次运行程序却看不到所有数据 从新做人 求救:在NT Server下调用GetVolumeInformationA取分区序列号,返回结果为负数!!!怎么回事啊? 正式到新公司上班,送300分,感谢在我最困难的时候在“软件工程”版给过我帮助的朋友们!! 请问斑竹及所有人,怎样得到QuickReport的总页数? Websphere3.5的一个BUG.希望有人反对.多谢.. 什么是DAMAP的对象 哪里有 winpcap 或 libnet 及其他网络编程辅助包下载? 谁能提供PSP文档?最好是Humphrey的那本书! 代码出现bebug.请大家帮我找!!!! TO:net_lover(孟子E章),详情请入内! 有谁用过DEV express系列的dxdbgrid??它是如何把一个文本文件txt读到dxdbgrid1.columns[i]的picklist中去,作为picklist的内容的啊? 我想在Linux下做数据库开发,用什么数据好? 我的pws可能出了问题,那位高手能解决一下 关于控制winamp 各位同行你们有这个的源程序吗(Cacio DT-900数据采集器) Html Help 制作方法 luodi(无知者无畏), 请进: 我用shell(app.path+"\mdac.exe"),来调用微软数据访问控件2.0,提示出错:命令行语法错误, 求救:如何将剪贴板中的内容放到image控件上 how to get the sytax of customer user object ? jsp中的打印问题 pb中有没有类似iif之类的语句 大虾们,怎样将String 类型转换成float 请问在及时战略中,怎么实现寻路的 我想在状态栏显示时间,有没有属性可以让时间自动变化,而不用其它辅助控件? 不会没人愿意回答这个问题吧,都贴第二次了!! 吃西瓜 我在注冊自創構件時總是出錯,請各位幫忙解決. 关于ado连接sybase的问题,紧急求救!!!(我的最高分了) 29分:flexcell定位 请教一下,关于Delphi COM类型库的问题 大家来谈谈申奥成功对我们的影响吧,我想知道怎么利用这个契机大赚一笔 各位谁喜欢“后街男孩”??喜欢的给分! 请问在DBGRID中改变当前选定行的颜色? 我想在DataSourceDataChange()中实现。 客户端怎么与服务器端通信 为什么我在窗口里修改了一个记录的图片字段后,在数据窗口内不能正常显示? 我要在RedLinux71下安装WEB服务器软件,请部如何做? 如何计算某年某月的天数和每天对应的星期 help!!! 为什么我的D6在编译时出现错误:“Fatal Error QuickRpt.pas(23):File not found:'Dsgnintf.dcu' 99又7分之1乘以99简算 99x99+99 用简便方法怎样算 小学数学16*25+15*2简便算法 101乘以99乘以999加999 急... 99x99十199要求用简便方法计算, 计算2008又2007分之1*2008分之2007 101乘以99/100 99x99十199简便方法怎么计算. 求底面半径为5厘米,侧面展开为正方形的圆柱体的侧面积、表面积和体积. 如何简便算49+49×49,意思,为什么这么算偶承认偶童鞋没文化.....(没文化真可怕)数学很伟大 西游记中8至几回是总写唐僧师徒历经九九八十一难? 一个圆柱体的底面直径是4厘米,它的侧面积是( )表面积是( ),体积是(一个圆柱体的底面直径是4厘米,它的侧面积是( )表面积是( ),体积是( ) 简便计算:41×49-49 《西游记》为什么唐僧师徒要经过九九八十一难才能取回真经?这八十一难意味着什么? 一个圆柱体高10厘米,底面半径5分米,表面积是多少? 两个数的和为10,设其中一个数为x,那么它们的积y是如何随x的变化而变化的?你能分别用函数表达式、表格和图像表示这种变化么 3.41-1.97+0.49-1.03的简便计算 西游记九九八十一难都有什么? 把两个相同的三位数连续写在一起,就得到一个六位数请你是说明任何一个连续数都可被7、11、13整除 41*101怎样简便就怎样算 求西游记中孙悟空他们经历的九九八十一难的名称劫难的名称和妖怪的名称(每个劫难)还有其下场,相当于把西游记的九九八十一难的浓缩成八十一小故事 开头 过程(经历) 结局(+妖怪 1.11.13.6这几个数怎么组成24?加减乘除随便用 41×101=? 请简便计算 1,19,199,1999,2099,19999怎么念? 在6,13,35三个数中与8的最大的公因数是1的是() 199乘49加199乘50加199怎么简便运算? 1+1/1+2+1/1+2+3+……+1/1+2+3+……+2004+2005如何计算 一个数加上20分之13的和再减去5分之3,差是20分之3,求这个数. 72x0.81+10.4简便运算 计算(2/1+3/1+...+2005/1)x(l+2\1+2005\1)x(2\1+3\1+...+2004\1) 一个数加上13/20得和,再减去3/5,差是3/20,这个数是多少 (5x一3)(5x一3)=4分之81,x=? 计算:1+2+3+…+2002+2003+2002+…+3+2+1=? 5与4的积被一个数除,商是0.5,个数是多少? √81+5x³=-31 这个怎么算呢. 从1/1*2+1/2*3+.+1/2002*2003怎么计算 1/2与2/3的积减去1/6,所得的差去除5/12,商是多少? 2.5x(40十4十0.4)简便计算? 计算: 1÷(1×2)+1÷(2×3)+… +1÷(2002×2003),请高手请点,谢谢 分解质因数 27= 30= 54= 递等式计算:(能巧算的要巧算) 2.8*0.9 5.4*10.1 计算1+2+3+...+2002+2003+2002+...+3+2+1 54分解质因数 递等式计算(能简便计算的要简便计算) 1、10.7-2.9×0.2×0.5 简算 2004+200.4+20.04+2.004 54怎么分解质因数 20-19+18-17...+4-3+2-1递等式简便方法 2004+200.4+20.04+2.004等于多少? 30分解质因数 简便计算 (1-1/2012)+(2-2012*2)+(3-1/2012*3)+...(2012-1/2012*2012) 9.05*2.01 怎样简算 把30分解质因数?具体数字 999x999怎么简便方法计算呀 递等式计算,用简便算法.要用乘法运算定律、加法运算定律、除法运算性质、减法运算性质.快,好的重分酬谢!(4.2-0.4×6)÷4== (15300÷600+67.5)×180==10500÷(10500÷25×1.25)==[(5.84- 99乘24简便脱式计 288十199=?(用简便方法计算) 125*1.25*0.125*8*.08*0.008*4*0.4*0.004*25*0.25*2.5=?(用简便算法计算).08改成0.8 负九十九又九十九分之九十八乘一百九十八 简便计算 99X99十199怎简便计算 桌上摆了两盘奶糖,共50块,如果从甲盘子里面拿走5块放到乙盘子里,那么两个盘子的奶糖一样多,原来两个盘子里各有多少奶糖.
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn