有什么方法可以删除(或本地化)目标文件中的符号?我正在Linux上寻找类似objcopy --keep-global-symbol
的东西。
或者也许有一种方法可以告诉链接器哪些符号应该隐藏?我找到了此页面:https://msdn.microsoft.com/en-us/library/28d6s79h.aspx,该页面描述了.Def文件,从阅读中我得到的印象是,我不仅可以将这些文件用于dll,还可以用于静态库。这是真的吗?
我需要这个,因为我链接了两个导出相同符号的库A和B。 A是动态链接的,而B是静态链接的。如果一个符号同时由A和B导出,我希望我的应用程序使用A中的符号,而且我想使用B中的一些符号(仅在B中)。
答案 0 :(得分:1)
如果您安装Mingw GCC端口之一,例如mingw-w64,
那么您还将获得Windows PE二进制文件的binutils
端口,并且可以使用
熟悉的objcopy --keep-global-symbol
。
在所选安装的bin
目录中找到它,例如C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev0\mingw64\bin
但是...
您可能在这里有一个XY problem, 因为链接器将解析输入序列中第一个库中的符号 定义它并忽略以后的库中的定义;这样您就可以 只需通过在静态链接之前将其链接即可优先选择DLL中的定义 图书馆。插图:
foo_static.c
#include <stdio.h>
void foo(void)
{
puts("foo_static");
}
bar_static.c
#include <stdio.h>
void bar(void)
{
puts("bar_static");
}
foo_dynamic.c
#include <stdio.h>
__declspec(dllexport) void foo(void)
{
puts("foo_dynamic");
}
gum_dynamic.c
#include <stdio.h>
__declspec(dllexport) void gum(void)
{
puts("gum_dynamic");
}
编译*_static.c
源文件并将目标文件存档在静态库static.lib
中:
>cl -c *_static.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
bar_static.c
foo_static.c
Generating Code...
>lib -out:static.lib *_static.obj
Microsoft (R) Library Manager Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
编译*_dynamic.c
源文件并将目标文件链接到DLL dynamic.dll
中:
>cl -c *_dynamic.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
foo_dynamic.c
gum_dynamic.c
Generating Code...
>link -dll -out:dynamic.dll *_dynamic.obj
Microsoft (R) Incremental Linker Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
Creating library dynamic.lib and object dynamic.exp
请注意,功能foo
在static.lib
和dynamic.dll
中已定义(不同)。
bar
仅在static.lib
中定义。 gum
仅在dynamic.dll
这是一个调用foo
,bar
和gum
的程序源:
main.c
extern void foo();
extern void bar();
extern void gum();
int main()
{
foo();
bar();
gum();
return 0;
}
我们编译的:
>cl -c main.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
main.c
然后我们像这样链接程序prog
:
>link -out:prog.exe main.obj static.lib dynamic.lib
Microsoft (R) Incremental Linker Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
首先使用static.lib
。程序输出:
>prog.exe
foo_static
bar_static
gum_dynamic
因此,foo
是从static.lib
解析而定义是
dynamic.dll
被忽略了。
现在,让我们以相反的顺序重新链接库,然后再次运行prog
:
>link -out:prog.exe main.obj dynamic.lib static.lib
Microsoft (R) Incremental Linker Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
>prog.exe
foo_dynamic
bar_static
gum_dynamic
这次,foo
从dynamic.dll
解析,定义从static.lib
解析
被忽略了。