在 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

请注意函数 foostatic.libdynamic.dll 中定义(不同)。 bar 仅在 static.lib 中定义。 gum 仅在 dynamic.dll

中定义

这里是调用foobargum的程序源:

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 定义的 被忽略了。