Как сгенерировать DLL из существующего кода C++, используя файл DEF в Visual Studio 2010

Я унаследовал проект C++, и мне нужно преобразовать его в DLL, чтобы использовать его в других проектах.

Код создан в решении Visual Studio 2010. Я могу скомпилировать его и сгенерировать файл DLL, но нет связанного файла lib. Я не разработчик Windows, но мне кажется, что мне нужно экспортировать функции, которые я хочу использовать, и есть два способа:

Первый вариант подразумевал бы ручное добавление __declspec(ddlexport) перед каждым классом или функцией, которую я хочу экспортировать. Поскольку существует много классов, и я не контролирую все приложения, которые будут связываться с библиотекой, второй вариант (файлы DEF) выглядит более перспективным.

Есть ли способ создать файл DEF из существующего файла DLL? Я пробовал разные решения:

  • Использование expdef. Это просто сбой без информации вообще.
  • Использование мусорной корзины. Я не вижу названия функций. Просто это:

    Тип файла: DLL

    Резюме

        1000 .data
        2000 .idata
       18000 .rdata
        5000 .reloc
        1000 .rsrc
       98000 .text
       48000 .textbss
    

Ничего более. Я думаю, это означает, что я ничего не экспортирую. Но это именно то, что я пытаюсь сделать. Как мне это сделать?

2 ответа

Решение

После неоднократного столкновения с этой проблемой в течение пары лет я сегодня нашел решение. Это немного глупо, но на самом деле это может быть наилучшим способом с Visual Studio.

Поскольку вы не хотите экспортировать КАЖДЫЙ возможный символ (тем более что ваша DLL может включать в себя большие статические библиотеки), и вы не можете редактировать файлы с символами, которые вы хотите иметь доступными (для меня это потому, что они являются сторонними библиотеками который должен быть статически связан, чтобы следовать их шаблону использования), и DEF является лучшим решением.

Если у нас есть:

  • Приложение (EXE)
  • Библиотека (DLL)
  • Библиотека имеет файл.DEF, что означает, что при сборке символы, перечисленные в.DEF, будут экспортированы в библиотеку.DLL и перечислены в файле.LIB.
  • Файл.DEF пуст
  • Ссылки на приложения Библиотечный LIB-файл

СЕЙЧАС СТРОИТЬ!

ОК, мы получаем много ошибок компоновщика...Ошибки компоновщика

Теперь перейдите на вкладку "Вывод" и обратите внимание, что в тексте вывода есть имена символов в конце каждой строки ошибок компоновщика:

Текст ошибки компоновщика

Мы можем создать небольшой сценарий, который берет последнее "слово" каждой строки, снимает скобки и затем помещает его в файл DEF. И это работает!

Like I said it's a little hacky (since you only end up with the symbols used by the Application at that time). But actually since you don't want to export everything, and you might need symbols in the libraries which that library statically links, it's probably the most accurate way of going about this.

(NB: In my case it's mostly a problem with trying to get the plugin DLL have access to symbols in the application EXE)

Почему бы не указать создание имплиба в вашем проекте и перекомпилировать. Вот соответствующая информация. Это будет экспортировать все, и ваши другие проекты могут ссылаться на Implib (файл.lib), чтобы использовать эту DLL. Если, с другой стороны, вы хотите избежать экспорта всего в DLL, вам нужно создать API (предпочтительно C для совместимости с компиляторами сторонних разработчиков, если это даже так), а затем экспортировать только эти функции. Это можно сделать, создав небольшой текстовый файл, переименовав его в.def и добавив его в проект. Формат этого файла хорошо документирован в MSDN, но минимум, который вам нужен, выглядит примерно так:

LIBRARY MyDLLName
EXPORTS
    function1
    function2
    ....

Вышесказанное потребует использования точных названий функций в коде. Эти функции должны быть объявлены как внешние "C", чтобы избежать искажения имен в C++, и WINAPI для определения соглашения о вызовах для 32-битного кода. Однако ваши экспортированные имена могут быть более "читабельными", если вы напишите это так:

LIBRARY MyDLLName
EXPORTS
    exportedName1=internalFunctionName1
    exportedName2=internalfunctionName2
    ....

Для получения дополнительной информации о синтаксисе см. Здесь.

Другие вопросы по тегам