在 windows 上从目标文件中删除符号
Removing symbols from object file on windows
有什么方法可以删除(或制作本地)目标文件中的符号吗?我正在 linux.
上寻找类似 objcopy --keep-global-symbol
的内容
或者也许有一种方法可以告诉 linker 应该隐藏哪些符号?我找到了这个页面:https://msdn.microsoft.com/en-us/library/28d6s79h.aspx,它描述了 .Def 文件,我从阅读中得到的印象是我不仅可以将这些文件用于 dll,还可以用于静态库。这是真的吗?
我需要这个,因为我 link 有 2 个库 A 和 B,它们导出相同的符号。 A 是动态 linked,B 是静态 linked。如果符号由 A 和 B 导出,我希望我的应用程序使用来自 A 的符号,另外我想使用来自 B 的一些符号(仅在 B 中)。
如果您安装了 Mingw GCC 端口之一,例如mingw-w64,
那么您还将获得 binutils
用于 Windows PE 二进制文件的端口,您将能够使用
熟悉的 objcopy --keep-global-symbol
.
在您选择的安装的 bin
目录中找到它,例如C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev0\mingw64\bin
不过...
你可能在这里有一个XY problem,
因为 linker 将解析输入序列中第一个库中的符号
定义它并忽略以后库中的定义;所以你可以
仅通过在静态之前 linking 来优先使用 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
个源文件和 link 个 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
然后我们link一个这样的程序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
被忽略。
现在让我们重新[=106=] 将库的顺序颠倒过来,然后再次 运行 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
定义的
被忽略了。
有什么方法可以删除(或制作本地)目标文件中的符号吗?我正在 linux.
上寻找类似objcopy --keep-global-symbol
的内容
或者也许有一种方法可以告诉 linker 应该隐藏哪些符号?我找到了这个页面:https://msdn.microsoft.com/en-us/library/28d6s79h.aspx,它描述了 .Def 文件,我从阅读中得到的印象是我不仅可以将这些文件用于 dll,还可以用于静态库。这是真的吗?
我需要这个,因为我 link 有 2 个库 A 和 B,它们导出相同的符号。 A 是动态 linked,B 是静态 linked。如果符号由 A 和 B 导出,我希望我的应用程序使用来自 A 的符号,另外我想使用来自 B 的一些符号(仅在 B 中)。
如果您安装了 Mingw GCC 端口之一,例如mingw-w64,
那么您还将获得 binutils
用于 Windows PE 二进制文件的端口,您将能够使用
熟悉的 objcopy --keep-global-symbol
.
在您选择的安装的 bin
目录中找到它,例如C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev0\mingw64\bin
不过...
你可能在这里有一个XY problem, 因为 linker 将解析输入序列中第一个库中的符号 定义它并忽略以后库中的定义;所以你可以 仅通过在静态之前 linking 来优先使用 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
个源文件和 link 个 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
然后我们link一个这样的程序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
被忽略。
现在让我们重新[=106=] 将库的顺序颠倒过来,然后再次 运行 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
定义的
被忽略了。