最近工作中遇到需要调用别人的动态链接库,但是只有个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

最近工作中遇到需要调用别人的动态链接库,但是只有个dll文件,别的一概没有,这可怎么办呢。还有不少dll导出的都是类,直接显式调用不太方便,最后综合网上的办法,自己再写两个工具,终于实现了将dll导出lib文件,并同时生成.h头文件。        还是自己动手才能丰衣足食啊。=====================================================
各位从事应用开发工作的小伙伴们,我们在以往的项目开发工作中经常会调用三方的 DLL ,突然有一天我们发现 DLL 的. LIB 和.H 文件 丢失了,这让我们无法应用该 DLL 到我们的项目中,是不是感觉相当的郁闷。现在让我分享一种方法给大家去解决这个问题。 首先我们得获取该 DLL 导出 函数,就是知道我们能使用该库得哪些函数名。我们可以用dumpbin 这个命令查询 DLL 中的 导出 函数。例如我们有Test. dll 这个动态库。 DUMPBIN /EXPORTS DTest. dll ordinal hin
1.选择生成. dll 项目 文件 ; 2.编写自己的多个.h和.cpp 文件 , 当功能函数,或者所需要的接口或者类都给完成了之后,选择生成(而不是点击调试运行 Crtl+F5) 3.将生成的*. dll 和*. lib 文件 都直接 导出 到自定义的指定目录 4.VS 生成*.exe 文件 到指定目录 5.包含指定的.h和. lib 文件 夹,方便使用和调用。
1 基本概念 1.1 动态链接库 库是写好的现有的,并且可以复用的代码。现实开发中每个程序都要依赖很多基础的底层库,不可能每个功能都从零开始开发,因此库是必须存在的。库的本质是一种可执行的二进制 文件 ,可以被操作系统加载到内存中执行,库有两种:静态链接库(简称为静态库)和动态链接库(简称为动态库),所谓静态、动态是指链接,一个程序编译成可执行 文件 步骤如下图所示: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FgwmgSGt-1646739553600)(img\编译过程.PN
如果要在 Python 中读取 Excel 文件 并生成 .h 头文件 ,可以使用 pandas 库。首先,使用 pandas 的 read_excel() 函数读取 Excel 文件 ,然后使用 to_csv() 函数将数据转换为 CSV 格式,最后使用 csv 模块将 CSV 文件 写入 .h 头文件 即可。 以下是一个简单的示例代码: import pandas as pd import csv # 读取 Excel 文件 df = pd.read_excel('file.xlsx') # 将数据转换为 CSV 格式 df.to_csv('file.csv', index=False, quoting=csv.QUOTE_NONNUMERIC) # 将 CSV 文件 写入 .h 头文件 with open('file.h', 'w') as f: f.write('#ifndef FILE_H\n') f.write('#define FILE_H\n\n') with open('file.csv', 'r') as csv_file: reader = csv.reader(csv_file) for row in reader: f.write(' '.join(row) + '\n') f.write('\n#endif') 在这段代码中,首先使用 pandas 的 read_excel() 函数读取 Excel 文件 ,然后使用 to_csv() 函数将数据转换为 CSV 格式。接着,使用 csv 模块的 reader() 函数读取 CSV 文件 ,并使用 for 循环将数据写入 .h 头文件