Я создаю 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
не предотвращает символы от библиотек от того, чтобы быть экспортируемым.
Вы можете использовать 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
, как обычно. Она может генерировать библиотеку импорта, если вам это нужно.
Оговорка: я делал это только в Linux, но AFAIK это должно работать и в Windows
Вы можете использовать опцию -fvisibility=hidden
; для получения дополнительной информации смотрите http://gcc.gnu.org/wiki/Visibility
Вы читали это на странице, на которую указали ссылку, относительно поведения, если --export-all-symbols не используется явно - автоматический экспорт отключен, если:
Любой символ в любом объектном файле был {{1} } помечены атрибутом __declspec (dllexport) .
Вы пробовали явно экспортировать только интересующие вас функции? Очень легко ошибиться с именами в файле DEF из-за искажения, поэтому этот метод должен быть более надежным.