Генерация .lib из DLL с помощью Visual Studio

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
7,864
Реакции
6,621
Программисты часто имеют дело со сторонними DLL, написанными третьими лицами, функции которых нужны при разработке. Это разумно и полезно, поскольку до тех пор, пока интерфейс DLL остается прежним, слинкованные с ней другие DLL-и могут легко заменяться без повторной компиляции и пересборки кода.

Однако, в Visual Studio чтобы прилинковать к коду стороннюю библиотеку, нужно иметь файл .lib, — самой по себе DLL для этой задачи недостаточно. К счастью, существует способ сгенерировать .lib из DLL с помощью Visual Studio. Создание файла .lib напоминает реверс-инжиниринг содержимого DLL.


1. Не обращая внимание на версию вашей Visual Studio, будь то 2003, 2005 или 2008 .NET, откройте командную строку Visual Studio Tools (обычно, что-то вроде Start -> Program Files -> Microsoft Visual Studio -> Visual Studio Tools -> Visual Studio Command Prompt).

2. Если у вас уже есть файл .def для вашей DLL, можете пропустить этот шаг. В противном случае, если ваша DLL не снабжена файлом .def, вам придется немного поработать, как описано ниже. Вы не можете сгенерировать .lib без файла .def, извините. Для генерации файла .def из DLL, выполните команду dumpbin для извлечения имен функций из вашей DLL. В нашем примере мы будем работать с sqlite3.dll.

Код:
dumpbin /exports C:\path\to\sqlite3.dll

Вывод можете видеть ниже:

dumpbin.jpg


Обведённые красным имена функций — это то, что вас интересует. Аккуратно скопируйте эти имена функций в новый текстовый файл с расширением .def. В начало этого нового файла поместите "EXPORTS" без кавычек, а затем каждую функцию в отдельной строке, как показано ниже:
Код:
EXPORTS
sqlite3_aggregate_context
sqlite3_aggregate_count
sqlite3_auto_extension
sqlite3_bind_blob
sqlite3_bind_double
sqlite3_bind_int
sqlite3_bind_int64
...

3. Взяв свой новый файл определений, вы можете выполнить в командной строке команду lib для окончательной генерации файла .lib:
Код:
lib /def:C:\path\to\sqlite3.def /out:C:\path\to\sqlite3.lib /machine:x86
Создав таким способом файл .lib вы можете использовать его для линковки в файлах своего проекта. Заметим, что аргумент "/machine" может принимать сколько угодно конфигураций компьютера, так что постарайтесь указать правильные. Для получения списка всех типов машин, просто наберите "lib" саму по себе. Приведем ниже вывод этой команды вам в поучение:
Код:
usage: LIB [options] [files]

options:

/DEF[:filename]
/EXPORT:symbol
/EXTRACT:membername
/INCLUDE:symbol
/LIBPATH:dir
/LIST[:filename]
/MACHINE:{AM33|ARM|EBC|IA64|M32R|MIPS|MIPS16|MIPSFPU|MIPSFPU16|
MIPSR41XX|SH3|SH3DSP|SH4|SH5|THUMB|X86}
/NAME:filename
/NODEFAULTLIB[:library]
/NOLOGO
/OUT:filename
/REMOVE:membername
/SUBSYSTEM:{CONSOLE|EFI_APPLICATION|EFI_BOOT_SERVICE_DRIVER|EFI_ROM|
EFI_RUNTIME_DRIVER|NATIVE|POSIX|WINDOWS|WINDOWSCE}[,#[.##]]
/VERBOSE
И если вы пришли на эту страницу в поисках sqlite3.lib, мы сэкономили вам немало времени :)

Напишем скрипт PowerShell для автоматизации генерации dll->lib:
PowerShell:
$pattern = "\s+[A-Z0-9]+\s+[A-Z0-9]+\s+[A-Z0-9]{8} (?.*)";
$platform = "x86";

if($args.length > 0)
{
    if($args[1])
    {
        $platform = $args[1];
    }

    $dll = [System.IO.Path]::GetFilename($args[0]);
    $def = [System.IO.Path]::ChangeExtension($dll, "def");
    $lib = [System.IO.Path]::ChangeExtension($dll, "lib");

    Write-Host ("Generating " + $def + " file…");
    "EXPORTS" > $def;
    &"dumpbin" "/exports" $args[0] | select-string $pattern | %{$null = $_.Line -match $pattern; ("`t" + $matches['symbol']) >> $def; }

    Write-Host ("Generating " + $lib + " file…");
    &"lib" ("/def:" + $def) ("/out:" + $lib) ("/machine:" + $platform) | out-null;

    Write-Host ("");
}
else
{
    Write-Host "Start powershell from VisualStudio commandline then use this script.";
    Write-Host "Script takes two parameters: dll filename and platform.";
    Write-Host "example: .\GenerateLibFromDll.ps1 hello.dll `"x64`"";
    Write-Host "or to process all dlls in the dir: gci *.dll | foreach {&`".\GenerateLibFromDll.ps1`" $_.Name `"x64`"}";;
}

Перевод: Дмитрий Скоробогатов.
 
Назад
Сверху Снизу