Как импортировать в Microsoft Visual C ++ - PullRequest
6 голосов
/ 28 октября 2010

У меня есть DLL, и я хотел бы использовать некоторые из ее функций.

#include <iostream>

using namespace std;

extern "C" __declspec(dllimport) int Initialize(char* localPort, char* adminServerName, int rpcTimeout);


int main()
{
    int res = Initialize("7864", "6000@kabc", 10000);

    return 0;
}

У меня нет файла .lib библиотеки DLL, поэтому я все равно могу с ним связаться.Одна вещь, которая приходит мне в голову - это использовать функцию LoadLibrary, а затем использовать GetProcAddress ().Есть ли другой способ?

Когда я компилирую следующий код

  • ошибка LNK2019: неразрешенный внешний символ _ imp _Initialize, на который ссылается функция _main

  • фатальная ошибка LNK1120: 1 неразрешенная внешняя информация

Я получаю вышеуказанные ошибки

Я использую Windows и Visual Studio 2008

Ответы [ 3 ]

4 голосов
/ 28 октября 2010

Из вашей фразы довольно ясно, что вы используете Dev Studio, ту или иную версию.

Для того, чтобы неявно ссылаться на dll, VC ++ требуется файл .lib, никаких вопросов,Без .lib вы можете только явно загрузить dll, используя LoadLibrary и GetProcAddress.

К счастью, библиотеки импорта не содержат ничего, кроме экспортируемых символов dll, поэтому вполне законно просто создать проект dll в VC ++, который экспортируетидентичные символы, создайте его, а затем используйте полученный .lib-файл для доступа к целевой dll.

Хитрость в том, чтобы получить правильные символы: в зависимости от того, как была создана оригинальная dll, может быть некоторое украшение дляdeal with.

«Инициализировать» можно было экспортировать из dll несколькими способами при просмотре с помощью dependencywalker

  • «Инициализация» - либо экспортировалась через a.Файл DEF или через extern "C" __declspec(dllexport) int __cdecl Initialize(...
  • "_ Initalize @ 16" - был экспортирован с использованием: extern "C" __declspec(dllexport) int __stdcall Initialize(...
  • ? Initialize @@ YAHPADOH @ Z "-` __declspec (dllexport) int Initialize (char *, char *, int);
  • ? Initialize @@ YGHPADOH @ Z "-` __declspec (dllexport) int __stdcall Initialize (char *, char *, int);

Проблемаlem действительно является первым случаем - если соглашение о вызовах не __cdecl (а большинство API-интерфейсов DLL на самом деле __stdcall - все dll-окна - __stdcall), то вы должны использовать файл .def для экспорта недекорированных имен.

1 голос
/ 28 октября 2010

В visual studio вы не можете напрямую связываться с DLL, вам нужна библиотека для импорта.

Так что в основном у вас есть несколько вариантов:

  1. Создание библиотеки импорта формы dll и ссылки на нее. В комплект поставки MinGW входят некоторые инструменты, которые действительно могут работать на вас, AFAIK, также есть некоторые инструменты для MSVC.

    Это может быть полезно: http://support.microsoft.com/kb/131313, сам не проверял

  2. Использовать GetProcAddress
  3. Используйте gcc, как известно, для прямой связи с DLL без библиотеки импорта :-)
1 голос
/ 28 октября 2010

Хорошим способом было бы восстановить некоторый заголовок, который бы объявлял функции, которые вы хотите вызвать. Для этого вы должны знать / обнаруживать их точные подписи.

Если у вас есть доступ к команде strings (доступной в cygwin), вы можете запустить ее с библиотекой DLL. В нем будут перечислены последовательности из более чем 4 последовательных печатаемых символов, оканчивающихся на 0 (обратите внимание, что это действительно легко реализовать в случае, если вы не хотите устанавливать cygwin). Среди этих «строк» ​​у вас будут мусорные и сигнатуры функций, искаженные компилятором C ++ (см .: http://en.wikipedia.org/wiki/Name_mangling).. Затем вам придется разобрать интересующие вас строки, используя undname.exe (при условии, что DLL была построена Microsoft Visual; см .: http://msdn.microsoft.com/en-us/library/5x49w699.aspx)

... Вы также можете рассмотреть DependencyWalker.

...