Удаление символов из объектного файла в Windows - PullRequest
0 голосов
/ 11 октября 2018

Есть ли способ удалить (или сделать локальными) символы в объектном файле?Я ищу что-то вроде objcopy --keep-global-symbol в Linux.

Или, может быть, есть способ сказать компоновщику, какие символы должны быть скрыты?Я нашел эту страницу: https://msdn.microsoft.com/en-us/library/28d6s79h.aspx, которая описывает файлы .Def, и мое впечатление от чтения таково, что я могу использовать эти файлы не только для DLL, но и для статических библиотек.Это правда?

Мне это нужно, потому что я связываюсь с 2 библиотеками A и B, которые экспортируют одинаковые символы.A связан динамически, а B связан статически.Если символы экспортируются как A, так и BI, я хочу, чтобы мое приложение использовало символы из A, плюс я хочу использовать некоторые символы из B (которые есть только в B).

1 Ответ

0 голосов
/ 15 октября 2018

Если вы установите один из портов 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 , потому что компоновщик разрешит символ из первой библиотеки во входной последовательности, которая его определяет, и проигнорирует определения в последующих библиотеках;так что вы можете отдать предпочтение определениям из 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 было проигнорировано.

...