DLL导出lib文件和.h头文件

   最近工作中遇到需要调用别人的动态链接库,但是只有个dll文件,别的一概没有,这可怎么办呢。还有不少dll导出的都是类,直接显式调用不太方便,最后综合网上的办法,自己再写两个工具,终于实现了将dll导出lib文件,并同时生成.h头文件。
    
    还是自己动手才能丰衣足食啊。

=========================================================================

问题:如果手上只有一个DLL文件,没有lib文件.h头文件,程序里怎么调用它

方法当然很简单,
先用VC的工具Depends.exe查看导出函数的函数名啊
用IDAPro或者其他反汇编工具分析函数原型
再用API函数:LoadLibrary,GetProcAddress
完成!

但是……如果Dll导出的是一个个的类呢,这就稍微有点麻烦

========================================================================

方法1:还是用显式调用,LoadLibrary,GetProcAddress,
这时候就要在头文件里声明一个个的“类成员函数的函数指针”了,
把GetProcAddress返回值赋给这些指针,使用时调用指针即可。

如何知道类的成员函数原型是长什么样的呢?
还是Depends工具,如果直接看,会发现导出函数名中有好多"?","@"等符号,

Depends的上面有个按钮"C++"(如果没有这个按钮,说明你的Depends太老了,下载个新的吧),点了这个按钮,再看看函数名有啥变化,是不是变得比较好理解了
不过Depends解析得还不够完全,看不出来成员函数是public、protected还是private,也不知道调用约定是__cdecl、__stdcall还是__fastcall,是虚函数还是静态成员函数。
如果要知道这些,还是用VC的undname.exe看得比较全面。

=======================================================================

方法2:用lib文件进行隐式链接,这样无需LoadLibrary,个人感觉比较方便的
如何生成lib文件呢,假设动态链接库名为example.dll,步骤如下

1、执行dumpbin.exe/EXPORTS example.dll>example.def
生成了一个def文件,里面的内容大概是下面这样:
   ordinal hint RVA      name
       1    0 00004570?function1@@
       2    1 00004540?function2@@

2、编辑这个def文件,删掉没用的信息,将它整理成这样的格式 :
        LIBRARY "example"
        EXPORTS
        ?function1@@    @1
        ?function2@@    @2
上面的@1和@2是根据第1个步骤中的ordinal序号来的

这个步骤我写了个程序HandleDef.exe来自动修改,否则太多函数的话手动改就累死了

3、运行lib.exe/def:example.def
生成了example.lib和example.exp文件。这个lib文件就可以在VC里用了,
比如这样    #pragma comment(lib,"example.lib")

4、新建一个文件example.tmp,里面保存函数名
?function1@@
?function2@@
然后运行undname.exeexample.tmp>example.txt
这样函数名就解析到example.txt文件里了

5、自己写了个HandleTxt.exe程序,把example.txt转换为example.h
转换后变成类似下面这样:

1.       class __declspec(dllimport) CExample  

2.       {  

3.       public: int function1(void);  

4.       public: void function2(char);  

5.       };  

这个样子的基本就能直接拷到VC里用了。
不过,如果自己的程序要用到构造函数来新建一个对象的话,对导入类进行声明的时候要事先分析好类对象的内存分布(这可不是个简单的事啊),上面这个CExample类应该这样声明

1.       class __declspec(dllimport) CExample  

2.       {  

3.       public: int function1(void);  

4.       public: void function2(char);  

5.       public: BYTE m_data[256];  

6.       };  

//上面m_data具体多少个字节,要靠自己反汇编分析,没法自动生成,具体方法比较麻烦,有兴趣的可以去网上查一些C++类的反汇编资料。

==========================================
总结:
为了方便,把以下内容写到一个批处理文件中
set name=example

dumpbin.exe/EXPORTS %name%.dll>%name%.def
HandleDef.exe %name%.def
lib.exe /def:%name%.def /MACHINE:IX86
undname.exe %name%.tmp>%name%.txt
HandleTxt.exe %name%.txt

执行完之后生成lib文件和h文件。
=========================================

上面提到的HandleDef.exe和HandleTxt.exe是我自己用C#写的小程序。

写了这么多,也不知道有没有人会感兴趣。

注:我这个还只是适用于VC编写的dll导出的类

如果用extern"c"导出的函数,除了自己反汇编分析原型,貌似没有别的办法

如何调用非VC编译器编译出来的类,暂时未研究过。


 

下载地址:http://pan.baidu.com/netdisk/singlepublic?fid=795627_2574562052

 

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值