Для тех, кто работает в Linux и хочет создать соответствующую библиотеку импорта (.lib) для .dll, созданной MinGW, здесь снова нужно выполнить два шага:
- Создать файл .deffrom .dll
- Создать .lib файл из .def
Используя MSVC, можно обработать вывод dumpbin /exports foo.dll
.В Linux вы должны обработать вывод objdump -p
(из binutils).Сгенерированный файл определения модуля должен выглядеть следующим образом:
LIBRARY foo.dll
EXPORTS
your_symbol @1
another_symbol @2
; ... et cetera
Чтобы преобразовать файл .def в файл .lib, используйте llvm-dlltool (MinGW (binutils) dlltool
is не подходит).Пример вызова для 64-битной библиотеки:
llvm-dlltool -m i386:x86-64 -d foo.def -l foo.lib
Объяснение:
-m i386:x86-64
: создать 64-битную библиотеку.Используйте -m i386
, если вам нужна 32-битная библиотека. -d foo.def
: чтение экспортированных символов из файла foo.def
-l foo.lib
: запись библиотеки импорта в foo.lib
- Если файл
.def
не содержит строку LIBRARY
, необходимо добавить параметр -D foo.dll
(с просто именем файла и без префикса каталога).
А вот скрипт для его автоматизации:
# Given libxyz-1.dll, create import library libxyz-1.lib
make_implib() {
local machine=$1 dll="$2" dllname deffile libfile
dllname="${dll##*/}"
deffile="${dll%.dll}.def"
libfile="${dll%.dll}.lib"
# Extract exports from the .edata section, writing results to the .def file.
LC_ALL=C objdump -p "$dll" | awk -vdllname="$dllname" '
/^\[Ordinal\/Name Pointer\] Table$/ {
print "LIBRARY " dllname
print "EXPORTS"
p = 1; next
}
p && /^\t\[ *[0-9]+\] [a-zA-Z0-9_]+$/ {
gsub("\\[|\\]", "");
print " " $2 " @" $1;
++p; next
}
p > 1 && /^$/ { exit }
p { print "; unexpected objdump output:", $0; exit 1 }
END { if (p < 2) { print "; cannot find export data section"; exit 1 } }
' > "$deffile"
# Create .lib suitable for MSVC. Cannot use binutils dlltool as that creates
# an import library (like the one found in lib/*.dll.a) that results in
# broken executables. For example, assume executable foo.exe that uses fnA
# (from liba.dll) and fnB (from libb.dll). Using link.exe (14.00.24215.1)
# with these broken .lib files results in an import table that lists both
# fnA and fnB under both liba.dll and libb.dll. Use of llvm-dlltool creates
# the correct archive that uses Import Headers (like official MS tools).
llvm-dlltool -m "$machine" -d "$deffile" -l "$libfile"
rm -f "$deffile"
}
# Example invocations:
make_implib i386:x86_64 usr/x86_64-w64-mingw32/sys-root/mingw/bin/libgnutls-30.dll
make_implib i386 usr/i686-w64-mingw32/sys-root/mingw/bin/libgnutls-30.dll
(Обратите внимание, что в llvm-dlltool есть ошибка, которая выдает файл .lib большего размера, чем необходимо, если имя библиотеки длиннеечем 15 символов. Помимо размера, он полностью функционален. Это исправлено https://reviews.llvm.org/D55860)
Протестировано с:
- llvm-dlltool из LLVM 7.0.0-1(Arch Linux)
- objdump из binutils 2.31.1-3 (Arch Linux)
- dlltool из binutils-mingw-w64-x86 64_2.30-7ubuntu1 + 8ubuntu1 (Ubuntu 18.04)
- link.exe из Visual Studio 2015 14.00.24215.1 (Windows 7)