Est-il possible de générer automatiquement une bibliothèque d'importation MSVC (fichier LIB) à partir d'une DLL? Comment?
Vous pouvez générer un fichier DEF en utilisant dumpbin/exports :
dumpbin /exports sqlite3.dll > exports.txt
echo LIBRARY SQLITE3 > sqlite3.def
echo EXPORTS >> sqlite3.def
for /f "skip=19 tokens=4" %A in (exports.txt) do echo %A >> sqlite3.def
Le bibliothécaire peut utiliser ce fichier DEF pour générer la LIB:
lib /def:sqlite3.def /out:sqlite3.lib /machine:x86
Tous les noms de fichiers (exports.txt
, sqlite3.dll
, sqlite3.def
, etc.) doit être précédé de chemins d'accès complets.
Je sais que le sujet est ancien, mais je n'ai toujours pas trouvé de script ou de fichier batch sur Internet pour le faire. Donc, basé sur la réponse de Dark Falcon, j'ai créé ce script, que vous pouvez enregistrer sous dll2lib.bat et exécuter:
REM Usage: dll2lib [32|64] some-file.dll
REM
REM Generates some-file.lib from some-file.dll, making an intermediate
REM some-file.def from the results of dumpbin /exports some-file.dll.
REM Currently must run without path on DLL.
REM (Fix by removing path when of lib_name for LIBRARY line below?)
REM
REM Requires 'dumpbin' and 'lib' in PATH - run from VS developer Prompt.
REM
REM Script inspired by http://stackoverflow.com/questions/9946322/how-to-generate-an-import-library-lib-file-from-a-dll
SETLOCAL
if "%1"=="32" (set machine=x86) else (set machine=x64)
set dll_file=%2
set dll_file_no_ext=%dll_file:~0,-4%
set exports_file=%dll_file_no_ext%-exports.txt
set def_file=%dll_file_no_ext%.def
set lib_file=%dll_file_no_ext%.lib
set lib_name=%dll_file_no_ext%
dumpbin /exports %dll_file% > %exports_file%
echo LIBRARY %lib_name% > %def_file%
echo EXPORTS >> %def_file%
for /f "skip=19 tokens=1,4" %%A in (%exports_file%) do if NOT "%%B" == "" (echo %%B @%%A >> %def_file%)
lib /def:%def_file% /out:%lib_file% /machine:%machine%
REM Clean up temporary intermediate files
del %exports_file% %def_file% %dll_file_no_ext%.exp
Je suis sûr que le script peut utiliser l'amélioration, mais j'espère que c'est utile.
Ce script crée * .lib à partir de * .dll transmis dans% 1:
@echo off
setlocal enabledelayedexpansion
for /f "tokens=1-4" %%1 in ('dumpbin /exports %1') do (
set /a ordinal=%%1 2>nul
set /a hint=0x%%2 2>nul
set /a rva=0x%%3 2>nul
if !ordinal! equ %%1 if !hint! equ 0x%%2 if !rva! equ 0x%%3 set exports=!exports! /export:%%4
)
for /f %%i in ("%1") do set dllpath=%%~dpni
start lib /out:%dllpath%.lib /machine:x86 /def: %exports%
Vous pouvez le nommer implib.bat et exécuter: implib.bat C:\folder\mydll.dll
qui produit C:\dossier\mydll.lib
Pour ceux qui sont sous Linux et souhaitent créer une bibliothèque d'importation appropriée (.lib) pour un .dll produit par MinGW, il y a encore deux étapes impliquées:
En utilisant MSVC, on pourrait traiter la sortie de dumpbin /exports foo.dll
. Sous Linux, vous devez traiter la sortie de objdump -p
(de binutils). Le fichier définition du module généré devrait ressembler à:
LIBRARY foo.dll
EXPORTS
your_symbol @1
another_symbol @2
; ... et cetera
Pour convertir le fichier .def en un fichier .lib, utilisez llvm-dlltool (MinGW (binutils) dlltool
est non approprié). Exemple d'appel pour une bibliothèque 64 bits:
llvm-dlltool -m i386:x86-64 -d foo.def -l foo.lib
Explication:
-m i386:x86-64
: générer une bibliothèque 64 bits. Utilisation -m i386
si vous avez besoin d'une bibliothèque 32 bits à la place.-d foo.def
: lire les symboles exportés du fichier foo.def
-l foo.lib
: écrire une bibliothèque d'importation dans foo.lib
.def
le fichier ne contient pas de ligne LIBRARY
, vous devez ajouter le -D foo.dll
option (avec juste le nom de fichier et aucun préfixe de répertoire).Et voici un script pour l'automatiser:
# 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
(Notez qu'il y a un bogue dans llvm-dlltool qui produit un fichier .lib plus volumineux que nécessaire si le nom de la bibliothèque est plus long que 15 caractères. Mis à part la taille, il est entièrement fonctionnel cependant. Il est résolu par https : //reviews.llvm.org/D5586 )
Testé avec:
Est-il possible de générer automatiquement une bibliothèque d'importation MSVC (fichier LIB) à partir d'une DLL? Comment?
En plus de la réponse de Dark Falcon, Microsoft a publié des procédures sur Comment créer des bibliothèques d'importation sans .OBJ ou source .
La première procédure de Microsoft est la même que celle de Dark Falcon. La deuxième procédure est un peu plus lourde, mais elle montre comment le faire avec un fichier objet à l'aide de stubs. Il fonctionne avec différentes conventions et classes d'appel.
Voici la deuxième procédure de la base de connaissances: