Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1632843
  • 博文数量: 584
  • 博客积分: 13857
  • 博客等级: 上将
  • 技术积分: 11883
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-16 09:34

分类: C/C++

2011-04-10 23:32:12

这里说的不是用LoadLibrary动态载入,虽然VC++用动态调用其实很容易,但很多VC++程序员很不习惯这种做法,因为要自己管理DLL的载入和释放,有的甚至不懂怎么动态调用DLL,已经依赖有H文件声明和导入静态库(LIB)方式。

所以一直以来困扰很多人,总是听到有人问,VC++怎么调用易的DLL?!

今天,我就来介绍这种在VC++常规的方法来调用易DLL。首先,我们需要一个小工具,这个工具是本人编写的,就是专门生成VC++需要的 DLL导入函数库,当然不是把易的DLL转成静态库,静态库也分几种,一种就是我们需要的,包含有DLL函数信息的库,C++调用DLL需要这个。我这个工具就是生成这种库的。

(219 K) 下载次数:347

下载工具以后,分两步骤,第一步从DLL中导出函数的名称说明文件*.Def,以“VCode.dll”为例,它生成的VCode.def文件是这样的:

LIBRARY Vcode.dll

EXPORTS
DeError   @1
DeInfo   @2
GetByteVcode  @3
GetFileVcode  @4
GetRecNum  @5
GetUrlVcode  @6
GetWebVcode  @7
LoadDe   @8

LIBRARY 易编的DLL名称,这个名称不能乱改的,要对应实际文件名,相当于LoadLibrary()的参数,改了程序就启动不了,而且提示框也是系统的,这和动调用DLL不同。

EXPORTS 后面跟着的就是DLL的所有导出函数名称,名称后面的由空格隔开的@XX数字是函数的序号,这也是不能改动的。

那么能改的是什么?只有函数名了。为什么要改函数名?

因为VC++对于C语言风格(extern "C" )的导入函数都是要上 _函数名@N 这种式样的修饰符,不然编译不了。易编写的DLL函数是不能编写这种名称的,所以在这里要自己动手修改,@N 的N是用数字表示(注意,和上面的@意义不同)这里@数字是表示函数的参数总字节数之和,即调用栈大小。就是由参数个数和类型决实的,通常是 参数个数 × 4 ,如果参数有日期型或长整数型或双精度小数型(非传址,即参考指针型),每有一个参数这些类型的就要再加4,因为这些类型是8字节的,相当于其它类型的两个参数,实际编译也是分两段两次入参数栈道的。

如果不会计算,那就更简单了,直接开始第二步骤,先别修改了,把刚才的*.Def编译成LIB静态库。

最后就是写C++需要的*.h文件了,上面有关于易DLL导出函数的声明,接着上例:

//导入函数表静态库文件(刚才我们编译出来的Vcode.LIB)
#pragma comment(lib, "Vcode.lib")

extern "C" //其它语言编译的DLL要用C风格
{
//DLL函数
int _stdcall LoadDe(char* strFilePath,char* strFilePath2);
....
}

然后编译VC++工程,是调用易DLL的,肯定会出错,你看看找不到函数了吧:

Linking...
VcodeDemoDlg.obj : error LNK2001: unresolved external symbol _DeInfo@4
VcodeDemoDlg.obj : error LNK2001: unresolved external symbol _DeError@4
VcodeDemoDlg.obj : error LNK2001: unresolved external symbol _LoadDe@8
VcodeDemoDlg.obj : error LNK2001: unresolved external symbol _GetUrlVcode@12
VcodeDemoDlg.obj : error LNK2001: unresolved external symbol _GetWebVcode@16
VcodeDemoDlg.obj : error LNK2001: unresolved external symbol _GetFileVcode@12
VcodeDemoDlg.obj : error LNK2001: unresolved external symbol _GetByteVcode@16

不过它也把要求的函数名列出来了,不用自己计算了,把这些@数字加到相应的函数后面,修改DEF文件,如下:

LIBRARY Vcode.dll

EXPORTS
DeError@4                   @1
DeInfo@4                    @2
GetByteVcode@16        @3
GetFileVcode@12          @4
GetRecNum@16            @5
GetUrlVcode@12           @6
GetWebVcode@16         @7
LoadDe@8                    @8

这里有两个@也是跟数字,注意不要改错了,是改紧跟着函数名的。改好后重新编译LIB,再次构建VC++工程,这次全部通过了。

你把H文件,LIB文件和DLL文件三个文件拿给喜欢偷懒的VC++程序员,这次易和C++的合作就算圆满完成了。[em01]

阅读(1674) | 评论(2) | 转发(2) |
给主人留下些什么吧!~~

leibniz_zsu2011-07-21 09:54:01

flylink: GetByteVcode
GetFileVcode
声明能不能贴一下,谢谢.....
这个声明我也没有啊,呵呵

flylink2011-06-02 10:37:37

GetByteVcode
GetFileVcode
声明能不能贴一下,谢谢