我想看看静态库中的哪些函数(如果链接到dll中)将被导出。我该怎么做?
int foo(int i)
{ return i + 1; }
__declspec(dllexport) int bar(int i)
{ return i + 1; }
dumpbin /symbols mylib.lib
对这两个函数产生相同的信息。
00A 00000000 SECT4 notype () External | ?foo@@YAHH@Z (int__cdecl foo(int))
00B 00000020 SECT4 notype () External | ?bar@@YAHH@Z (int __cdecl bar(int))
我怎么知道bar()
会被导出而foo()
不会?
答案 0 :(得分:3)
Q1)
如何在Windows静态库中标识导出的函数?
这是一个问题,并且:
第二季度)
我想看看静态库中的哪些函数(如果链接到dll中)将被导出。我该怎么做?
是另一个问题。
第二季度
首先考虑第二季度:通过对静态库的任何检查,您都无法分辨出哪些全局符号 如果其中定义的静态库(包括DLL导出)将链接到任意DLL, 输入其链接。演示:
foo.c
__declspec(dllexport) int foo(int i) { return i + 1; }
bar.c
__declspec(dllexport) in bar(int i) { return i + 1; }
foomain.c
#include <windows.h>
__declspec(dllexport) int foo(int i);
BOOLEAN WINAPI DllMain( IN HINSTANCE hDllHandle,
IN DWORD nReason,
IN LPVOID Reserved )
{
return foo(1) == 2;
}
barmain.c
#include <windows.h>
__declspec(dllexport) int bar(int i);
BOOLEAN WINAPI DllMain( IN HINSTANCE hDllHandle,
IN DWORD nReason,
IN LPVOID Reserved )
{
return bar(1) == 2;
}
编译所有这些源文件:
>cl /c foo.c bar.c foomain.c barmain.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
foo.c
bar.c
foomain.c
barmain.c
Generating Code...
现在制作一个包含foo.obj
和bar.obj
的静态库:
>lib /out:foobar.lib foo.obj bar.obj
Microsoft (R) Library Manager Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
接下来,将DLL与输入foomain.obj
和foobar.lib
链接起来:
>link /out:foo.dll /dll foomain.obj foobar.lib
Microsoft (R) Incremental Linker Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
Creating library foo.lib and object foo.exp
最后,将另一个DLL与输入barmain.obj
链接,然后再次与foobar.lib
>link /out:bar.dll /dll barmain.obj foobar.lib
Microsoft (R) Incremental Linker Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
Creating library bar.lib and object bar.exp
声明在foo
中定义的两个函数bar
和foobar.lib
dllexport
。让我们看看foo.dll
导出了哪些符号:
>dumpbin /exports foo.dll
Microsoft (R) COFF/PE Dumper Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file foo.dll
File Type: DLL
Section contains the following exports for foo.dll
00000000 characteristics
FFFFFFFF time date stamp
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00001030 foo
Summary
2000 .data
6000 .rdata
1000 .reloc
B000 .text
只是foo
,而不是bar
。
bar.dll
的出口是什么?
>dumpbin /exports bar.dll
Microsoft (R) COFF/PE Dumper Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file bar.dll
File Type: DLL
Section contains the following exports for bar.dll
00000000 characteristics
FFFFFFFF time date stamp
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00001030 bar
Summary
2000 .data
6000 .rdata
1000 .reloc
B000 .text
只是bar
,而不是foo
。
从foo
链接到bar
或foobar.lib
,还是两者,或者都不链接
可执行文件或DLL取决于静态库中的哪些目标文件
在链接中。
静态库foobar.lib
只是一个存档(在Unix ar
archive format中)
可以提供给链接器的目标文件(foo.o
,bar.o
)的数量
选择进行可执行文件或DLL链接所需的文件(如果有)。链接器
从存档中仅提取那些目标文件,并将其准确地输入到链接中
就像您在链接器命令行中单独命名它们一样,而没有提及静态
图书馆。
链接器需要从静态库中提取的目标文件是那些 为 other 对象文件中产生的未解析引用提供定义 必须链接。
因此foo.dll
的链接如下进行:
foomain.obj
被链接是因为在命令行中命名的目标文件是无条件链接的。
foomain.obj
的链接引起对foo
的未解决引用。
因此,在foobar.lib
中搜索定义了foo
的目标文件。
发现归档成员foobar.lib(foo.obj)
提供了foo
的定义,因此将其提取并链接到foo.dll
。
另一个存档成员foobar.lib(bar.obj)
不提供任何未解析引用的定义,因此不会提取或链接该引用。
链接:
>link /out:foo.dll /dll foomain.obj foobar.lib
与完全相同:
>link /out:foo.dll /dll foomain.obj foo.obj
同样,链接:
>link /out:bar.dll /dll barmain.obj foobar.lib
与以下内容完全相同:
>link /out:bar.dll /dll barmain.obj bar.obj
静态库对链接没有任何贡献,除了目标文件 从中挑选出来的,如果有的话,取决于 链接中的其他目标文件。因此,您可以看到Q2等于:
如果我有一些定义了符号的目标文件,有些则声明为dllexport
,而有些则没有,如果给定0或更大的值,我该如何判断将从DLL中导出哪些符号那些目标文件被链接到其中了?
一根绳子要花多长时间?您需要获得一些实际DLL的实际链接,才能确定其DLL导出将是什么。
返回第一季度
同样,Q1等于:
如何识别Windows目标文件中的导出函数?
必须是可能的,因为链接程序可以做到。
我们通过运行以下命令检查了foo.dll
的DLL导出:
>dumpbin /exports foo.dll
,它报告了foo
。 dumpbin /exports FILE
是我们通常会询问的方式
DLL导出的FILE
是DLL或程序。它向我们显示了
FILE
的动态符号表。
dumpbin
知道静态库只是一袋目标文件。所以
>dumpbin /symbols foobar.lib
向我们显示了与以下两个相同的符号表:
>dumpbin /symbols foo.obj bar.obj
即
COFF SYMBOL TABLE
000 010463CB ABS notype Static | @comp.id
001 80000191 ABS notype Static | @feat.00
002 00000000 SECT1 notype Static | .drectve
Section length 3C, #relocs 0, #linenums 0, checksum 67EAC832
004 00000000 SECT2 notype Static | .debug$S
Section length 6C, #relocs 0, #linenums 0, checksum 0
006 00000000 SECT3 notype Static | .text$mn
Section length B, #relocs 0, #linenums 0, checksum B38E4E30
008 00000000 SECT3 notype () External | _bar
String Table Size = 0x0 bytes
COFF SYMBOL TABLE
000 010463CB ABS notype Static | @comp.id
001 80000191 ABS notype Static | @feat.00
002 00000000 SECT1 notype Static | .drectve
Section length 3C, #relocs 0, #linenums 0, checksum 1D7A1E73
004 00000000 SECT2 notype Static | .debug$S
Section length 6C, #relocs 0, #linenums 0, checksum 0
006 00000000 SECT3 notype Static | .text$mn
Section length B, #relocs 0, #linenums 0, checksum B38E4E30
008 00000000 SECT3 notype () External | _foo
String Table Size = 0x0 bytes
Likwise:
>dumpbin /exports foobar.lib
报告与以下命令相同的DLL导出-即 none -
>dumpbin /exports foo.obj bar.obj
并且必须为 none ,因为目标文件没有动态符号表。
链接器生成动态符号表。因此,仅由 链接器可以拥有一个。这意味着DLL或可执行文件。不是目标文件,这是 由编译器生成并由链接器使用。
链接器在DLL或可执行文件的动态符号表中记录
实际链接的对象文件中合格的dllexport
全局符号。
因此,foo.dll
导出了foo
,因为在存档中foo
被定为dllexport
链接到foobar.lib(foo.obj)
的成员foo.dll
。它不导出
bar
,尽管bar
在dllexport
中也被限定为foobar.lib(bar.obj)
因为该目标文件 not 未链接到foo.dll
因此,链接器检测 foo
中的dllexport
被定为foo.obj
,并且
在此基础上将foo
添加到foo.dll
的动态符号表中。
该限定条件采用 compiler 嵌入的链接器指令的简单形式
foo.obj
中的代码指示链接器导出符号foo
进行动态链接。
编译器发出该链接器指令,因为源代码声明了foo
与__declspec(dllexport)
。如果链接器链接,链接器将遵循该指令
通过将foo.obj
添加到动态符号表来foo
。您可以构建相同的foo.dll
完全不使用源代码中的__declspec(dllexport)
而是给出
自己在链接器命令行中使用链接器标志/export:foo
。
您因此可以通过要求dllexport
进行展示来检测foo
的{{1}}资格
您是编译器在dumpbin
中标出的链接器指令:
foo.obj
类似地:
>dumpbin /directives foo.obj
Microsoft (R) COFF/PE Dumper Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file foo.obj
File Type: COFF OBJECT
Linker Directives
-----------------
/DEFAULTLIB:LIBCMT
/DEFAULTLIB:OLDNAMES
/EXPORT:_foo <-- This
Summary
6C .debug$S
3C .drectve
B .text$mn
所以:
>dumpbin /directives bar.obj
Microsoft (R) COFF/PE Dumper Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file bar.obj
File Type: COFF OBJECT
Linker Directives
-----------------
/DEFAULTLIB:LIBCMT
/DEFAULTLIB:OLDNAMES
/EXPORT:_bar <-- And this
Summary
6C .debug$S
3C .drectve
B .text$mn
报告与以下两项相同的出口:
>dumpbin /directives foobar.lib
Microsoft (R) COFF/PE Dumper Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file foobar.lib
File Type: LIBRARY
Linker Directives
-----------------
/DEFAULTLIB:LIBCMT
/DEFAULTLIB:OLDNAMES
/EXPORT:_bar
Linker Directives
-----------------
/DEFAULTLIB:LIBCMT
/DEFAULTLIB:OLDNAMES
/EXPORT:_foo
Summary
D8 .debug$S
78 .drectve
16 .text$mn
这就是对Q1的答案。