Как сказать компоновщику MinGW не экспортировать все символы?

Я создаю Windows динамическая библиотека с помощью набора инструментальных средств MinGW.

Для создания этой библиотеки, я статически связываюсь с другими 2, которые предлагают API, и у меня есть a .def файл, где я записал единственный символ, я хочу быть экспортированным в моей библиотеке.

Проблема состоит в том, что GCC экспортирует все символы включая тех из библиотек, с которыми я связываюсь. Должен там так или иначе сказать компоновщику только для экспорта символов в def файл?

Я знаю, что существует опция --export-all-symbols но, кажется, не существует напротив него.

Прямо сейчас последняя строка сценария сборки имеет эту структуру:

g++ -shared CXXFLAGS DEFINES INCLUDES -o library.dll library.cpp DEF_FILE \
OBJECT_FILES LIBS -Wl,--enable-stdcall-fixup

Править: В документах о компоновщике это говорит это --export-all-symbols поведение по умолчанию и что оно отключено, когда Вы не используете ту опцию явно при обеспечении a def файл, кроме тех случаев, когда это не делает; символы в третьей стороне освобождают, экспортируются так или иначе.

Править: Добавление опции --exclude-libs LIBS или –exclude-symbols SYMBOLS не предотвращает символы от библиотек от того, чтобы быть экспортируемым.

13
задан James R. 11 May 2010 в 15:58
поделиться

3 ответа

Вы можете использовать dllwrap, если ваш дистрибутив binutils (родной или кросс-компилируемый) предоставляет его.

Он может создавать DLL, используя интерфейс в DEF-файле (под капотом он вызывает gcc, ld и dlltool для этого). Разница между использованием этой функции и передачей DEF-файла в GCC напрямую заключается в том, что определения в файле обрабатываются по-разному.

Например, если у вас есть переименование символов в файле экспорта:

_SomeFuntion = _SomeFunction@12

GCC создаст 2 экспорта, один с именем _SomeFunction и другой с измененным именем, в то время как dllwrap экспортирует только _SomeFuntion. Поэтому если вы добавите в DEF-файл только те символы, которые вы хотите экспортировать, то в итоге в библиотеке будут только они.

dllwrap по умолчанию использует драйвер компилятора C, поскольку у него нет возможности узнать иначе. Поскольку вы компонуете код на C++, вы должны использовать опцию --driver-name c++, чтобы установить драйвер. Если у вас есть исполняемые файлы MinGW с префиксом, вы должны включить его в имя драйвера (например, i686-mingw32-c++ вместо c++), и вам может понадобиться опция --dlltool-name.

Попробуйте использовать эти две строки вместо той, что вы написали:

g++ -c CXXFLAGS DEFINES INCLUDES -o library.o library.cpp
dllwrap -o library.dll --driver-name c++ --def DEF_FILE OBJECT_FILES LIBS -Wl,--enable-stdcall-fixup

Первая генерирует объектный файл из кода library.cpp, а вторая собирает динамическую библиотеку. В OBJECT_FILES (которые, как я предполагаю, являются другими объектными файлами, сгенерированными вами ранее) должен быть library.o.

При этом я должен сказать, что dllwrap уже устарел в 2006 году, и по нему нет документации в официальном пакете binutils; чтобы получить некоторую информацию, вы можете вызвать его с помощью --help, как обычно. Она может генерировать библиотеку импорта, если вам это нужно.

1
ответ дан 2 December 2019 в 01:41
поделиться

Оговорка: я делал это только в Linux, но AFAIK это должно работать и в Windows

Вы можете использовать опцию -fvisibility=hidden; для получения дополнительной информации смотрите http://gcc.gnu.org/wiki/Visibility

0
ответ дан 2 December 2019 в 01:41
поделиться

Вы читали это на странице, на которую указали ссылку, относительно поведения, если --export-all-symbols не используется явно - автоматический экспорт отключен, если:

Любой символ в любом объектном файле был {{1} } помечены атрибутом __declspec (dllexport) .

Вы пробовали явно экспортировать только интересующие вас функции? Очень легко ошибиться с именами в файле DEF из-за искажения, поэтому этот метод должен быть более надежным.

1
ответ дан 2 December 2019 в 01:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: