作者:ani_di
版权所有,转载务必保留此链接 http://blog.youkuaiyun.com/ani_di
从dll构建lib
利用lib来静态调用dll比传统的LoadLibrary要方便很多。有时候只有dll没有lib,但是我们还是有方法生成,下面是我的经验。(命令行操作,先自行进入VS的命令行工具)
Step 1. 头文件
如果有头文件请跳过。 一般dll的头文件这样定义的
#ifdef SOME_EXPORTS
#define SOME_API __declspec(dllexport)
#else
#define SOME_API __declspec(dllimport)
#endif
extern SOME_API int __stdcall foo();
所以自己定义的头文件一般这样写
extern __declspec(dllimport) int __stdcall foo();
有两点注意:
- 调用方式可能不是__stdcall。可以看foo的反汇编,如果函数返回是
ret 10h
,表示栈清理是在被调用方,是__stdcall;如果是ret
,则是__cdecl调用方式。 - 另一种常见导出方式是
extern "C"
这种C方式。区别也非常简单,C++的导出函数名会是_foo@@MKCLCK等,后面一堆符号,用工具可以看到参数名,类名等信息。
Step 2. 生成def文件
def文件可以手工生成。
dumpbin /exports some.dll
输出
Microsoft (R) COFF/PE Dumper Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file D:\Vim\vim72\gvimext.dll
File Type: DLL
Section contains the following exports for gvimext.dll
00000000 characteristics
489DCA77 time date stamp Sun Aug 10 00:48:55 2008
0.00 version
1 ordinal base
2 number of functions
2 number of names
ordinal hint RVA name
1 0 0000108C DllCanUnloadNow
2 1 000010B5 DllGetClassObject
Summary
2000 .data
1000 .idata
1000 .rdata
1000 .reloc
1000 .rsrc
2000 .text
手工编写def文件
LIBRARY SomeDll
EXPORTS
DllCanUnloadNow @1
DllGetClassObject @2
@1,@2是导出stub的序号,不能错了。
__stdcall的导出名还要加上参数长度,否则链接失败。
LIBRARY SomeDll
EXPORTS
DllCanUnloadNow@4 @1
DllGetClassObject@0 @2
Step 3. 生成lib
lib /def:some.def /out:some.lib /machine:x86
大功告成!现在只需要在代码中加入
#pragma comment(lib, "some.lib")