¿Cómo generar una biblioteca de importación (archivo LIB) desde una DLL?

¿Es posible autogenerar una biblioteca de importación de MSVC (archivo LIB) desde una DLL? ¿Cómo?

Puede generar un archivo DEF utilizando 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 

El bibliotecario puede usar este archivo DEF para generar el LIB:

 lib /def:sqlite3.def /out:sqlite3.lib /machine:x86 

Todos los nombres de archivo ( exports.txt , sqlite3.dll , sqlite3.def , etc.) deben agregarse a rutas completas.

Sé que el tema es antiguo, pero aún no pude encontrar un script o un archivo por lotes en Internet para hacer esto. Entonces, basado en la respuesta de Dark Falcon, hice este script, que puedes guardar como dll2lib.bat y ejecutar:

 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 

Estoy seguro de que el script puede mejorar, pero espero que sea útil.

Este script crea * .lib desde * .dll pasado en% 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% 

Podría llamarlo implib.bat y ejecutar: implib.bat C:\folder\mydll.dll que produce C: \ folder \ mydll.lib

¿Es posible autogenerar una biblioteca de importación de MSVC (archivo LIB) desde una DLL? ¿Cómo?

Además de la respuesta de Dark Falcon, Microsoft ha publicado procedimientos en Cómo crear bibliotecas de importación sin .OBJ o fuente .

El primer procedimiento de Microsoft es el mismo que el de Dark Falcon. El segundo procedimiento es un poco más engorroso, pero muestra cómo hacerlo con un archivo de objeto usando stubs. Funciona con diferentes convenciones de llamadas y clases.

Este es el segundo procedimiento de la KB:

  1. Cuando se usa “__declspec (dllimport)” en un prototipo o statement, cámbielo a “__declspec (dllexport)”.
  2. Para funciones que no devuelven un valor, para funciones C en origen C y para funciones C en código fuente C ++ (usadas con el constructo ‘extern’ C ”), reemplace el punto y coma que termina el prototipo de función con un par coincidente de llaves (“{}”).
  3. Para las funciones de C ++ (globales o miembros) que devuelven un valor, debe crear un cuerpo ficticio para la función y devolver un valor ficticio del tipo adecuado. (No tener una statement de devolución en la función es ilegal). Esto también se aplica a las funciones de los miembros de la clase. Tenga en cuenta que el objective de este procedimiento es engañar a la utilidad LIB para que genere la biblioteca de importación correcta, de modo que estos cuerpos ficticios no tengan ningún efecto.
  4. Para las clases de C ++, puede anular las funciones miembro mediante el uso de los prototipos en la statement de clase, siempre y cuando deshabilite la función en línea al comstackr.
  5. Los argumentos de función generalmente se especifican por tipo en un archivo de cabecera. Por ejemplo, Geta (int). Se debe especificar un identificador de argumento ficticio al agregar el cuerpo de la función ficticia Geta (int x). De lo contrario, se genera el error C2055.