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

Тема в разделе "Другие языки программирования", создана пользователем Dragokas, 9 апр 2016.

  1. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.476
    Симпатии:
    4.305
    Программисты часто имеют дело со сторонними 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.

    Код (Text):
    dumpbin /exports C:\path\to\sqlite3.dll
    Вывод можете видеть ниже:

    dumpbin.jpg

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

    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:
    Код (Text):

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

    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`"}";;
    }
     
    Перевод: Дмитрий Скоробогатов.
     
    Kиpилл нравится это.

Поделиться этой страницей