Поиск информации о dlltool --add-irect (-a)
Я ищу дополнительную информацию о параметре --add-irectal для dlltool. Когда вы используете эту опцию? Что оно делает?
Информация из binutils поможет по этой опции:
-a
--add-indirect
Указывает, что когда
dlltool
создает файл экспорта, он должен добавить раздел, который позволяет ссылаться на экспортируемые функции без использования библиотеки импорта. Что бы это ни значило, черт возьми!
1 ответ
Прежде всего, давайте проясним, что такое файл экспорта. Файл экспорта необходим для создания DLL. Этот файл связан с объектными файлами (созданными компилятором), которые составляют тело библиотеки DLL (т.е. функции, классы и т. Д.), И он обрабатывает интерфейс между библиотекой DLL и внешним миром. Это двоичный файл, и его можно создать, задав -e
возможность dlltool
когда он создает или читает в *.def
файл.
Следующий термин, который вы должны понять, это библиотека импорта. Один из способов использования DLL в некоторых потребительских приложениях - связать это приложение с DLL, чтобы потребителю были доступны все экспортированные функции из DLL. Такое связывание с библиотеками DLL обычно осуществляется путем ссылки на библиотеку импорта, которая, по сути, является вспомогательной статической библиотекой, содержащей таблицу адресов импорта (IAT), которая позволяет потребителю ссылаться на все экспортируемые функции библиотеки DLL. Например, каждая ссылаемая функция DLL содержит свою собственную запись в IAT. Во время выполнения IAT заполняется соответствующими адресами, которые указывают непосредственно на соответствующие функции в отдельно загруженной DLL.
Теперь давайте вручную создадим DLL с dlltool
а также gcc
чтобы дать вам понять, что происходит:
gcc -c library.c
производит library.o
,
dlltool -e exports.o -l library.dll.a library.o
производит файл экспорта exports.o
и импортировать библиотеку library.dll.a
(.dll.a
является стандартным суффиксом для библиотек импорта, созданным GCC, который подчеркивает, что библиотека импорта на самом деле статична с .a
, но нацелен на DLL с .dll
),
gcc library.o exports.o -o library.dll
производит library.dll
,
gcc consumer.o library.dll.a -o consumer
производит исполняемый файл consumer.exe
который связан с library.dll
,
ПРИМЕЧАНИЕ. Вышеприведенное является ручной процедурой создания DLL, и ее не рекомендуется использовать в производственной среде, поскольку GCC объединяет всю эту логику в одном оптимизированном вызове:
gcc -shared -o library.dll library.o -Wl,--out-implib,library.dll.a
Теперь, когда мы знаем основную терминологию и цель, мы можем легко интерпретировать то, что написано в справке о --add-indirect
:
Указывает, что когда
dlltool
создает файл экспорта, он должен добавить раздел, который позволяет ссылаться на экспортируемые функции без использования библиотеки импорта. Что бы это ни значило, черт возьми!
Давайте применим это к предыдущему примеру. В этом случае, exports.o
будет уже содержать IAT, и, следовательно, в результате library.dll
также будет содержать эту информацию, поэтому нам не нужно импортировать библиотеку library.dll.a
потому что теперь мы можем напрямую ссылаться на library.dll
сам:
gcc consumer.o library.dll -o consumer
Полезно это или нет - вопрос довольно субъективный. Я предполагаю, что с точки зрения нас (программистов / пользователей) это в значительной степени бесполезно, так как создание и связывание DLL не должно выполняться явно (т.е. посредством прямого вызова dlltool
) в любом случае, но лучше сделать это через интерфейс GCC (как отмечено выше). С точки зрения создания инструментов разработки, таких как цепочки инструментов (например, сам GCC), это может быть полезно, так как нечто подобное приведенному выше примеру может фактически использоваться за кулисами самой GCC для выполнения gcc -shared -o library.dll ...
и так далее.
Наконец, обычно не рекомендуется ссылаться на DLL напрямую. Хотя он отлично работает с последними версиями MinGW/MinGW-w64, в прошлом были ошибки. Кроме того, если псевдо-перемещение отключено, то прямая связь с DLL может привести к определенным проблемам во время выполнения. Кроме того, это официальный способ, которым MSVC связывает потребителей с библиотеками DLL, то есть без библиотеки импорта MSVC просто не может выполнить связывание, что также может быть причиной, по которой вы должны всегда использовать библиотеки импорта. Помните, что DLL не то же самое, что разделяемый объект (SO) в Linux: их варианты использования одинаковы, но их реализации основаны на различных технологиях.