Интернет, компьютеры, софт и прочий Hi-Tech

Подписаться через RSS2Email.ru

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

Программисты часто имеют дело со сторонними 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 /exports

    Обведённые красным имена функций — это то, что вас интересует. Аккуратно скопируйте эти имена функций в новый текстовый файл с расширением .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:

$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`"}";;
}

Перевод: Дмитрий Скоробогатов, 18.01.2012.
Оригинальный текст можно найти по адресу http://www.coderetard.com/2009/01/21/generate-a-lib-from-a-dll-with-visual-studio/.


Предыдущие публикации:

Биржа долевых инвестиций SIMEX.

Последнее редактирование: 2012-01-18 10:09:00

Метки материала: генерация, lib, dll, помощь, visual, studio, генерация lib, visual studio, lib из dll, dll с помощью visual studio, для windows, формат, форматы, по, софт, software, разработка по, софт для windows, документация для программиста, программное обеспечение


8 комментариев

02.06.2015 21:39:43 #
Google Chrome Гость Гость
Автору спасибо!
08.07.2014 13:53:21 #
Google Chrome Гость гость
Благодарю, очень помогла статья
11.09.2013 14:00:14 #
Mozilla Firefox dima
Пожалуйста Well
10.09.2013 20:23:55 #
Google Chrome Гость jhon
Спасибо огромное, и как раз попал сюда в поисках sqlite3.lib Very we!
19.01.2012 21:07:38 #
Mozilla Firefox dima
Гугл говорит, что в def-файл можно добавить алиасы проблемных функций. Например, так:
Text
LIBRARY "xyz.dll"
EXPORTS
MyProblemFunction
_MyProblemFunction@4 = MyProblemFunction

А файл lib генерировать уже с помощью этого def.
Не знаю, поможет ли Вам это, мне к алиасам прибегать не приходилось.
19.01.2012 19:23:54 #
Mozilla Firefox Гость
Там проблема в том, что они C++ - ые. А у VS конвенция имен кое-где другая.
19.01.2012 18:44:05 #
Mozilla Firefox dima
Про скомпилированные конкретно под VS не знаю, но однажды пришлось прилинковывать стороннюю DLL, написанную под Delphi, к своей библиотеке на C, компилируемой под MinGW. Если это удалось, то думаю и с VS такое прокатит.
 
Пусть дана example.dll с функциями ExampleFunction1, ExampleFunction2 и ExampleFunction3. Моя библиотека являлась расширением к SQLite. Делаем следующее:
  1. Пишем файл заголовка example.h типа следующего:
    C
    #include <windows.h>
     
    __declspec(dllimport) int ExampleFunction1(void);
    __declspec(dllimport) PChar ExampleFunction2(DWORD RK, PChar pin);
    __declspec(dllimport) int ExampleFunction3(PChar pin, PChar key);

  2. Создаем файлы example.def и example.lib, как описано в данной статье.
     
  3. Включаем в свой код
    C
    #include "example.h"

  4. Компилируем свою библиотеку командой
    Bash
    gcc -shared -Isqlite3 -o mylib.dll mylib.c -lexample
19.01.2012 17:45:08 #
Mozilla Firefox Гость
А вот как прилинковать dll, скомпилированный VS, в проект, собираемый с помощью mingw?
Смысл - включить в общую сборку проекта под линуксом мастадайного клиента.

Оставьте, пожалуйста, свой комментарий к публикации

Представиться как     Антибот:
   

Просьба не постить мусор. Если вы хотите потестить xBB, воспользуйтесь кнопкой предварительного просмотра на панели инструментов xBBEditor-а.


© 2007-2017, Дмитрий Скоробогатов.
Разрешается воспроизводить, распространять и/или изменять материалы сайта
в соответствии с условиями GNU Free Documentation License,
версии 1.2 или любой более поздней версии, опубликованной FSF,
если только иное не указано в самих материалах.