Проблема LNK2019 - PullRequest
       12

Проблема LNK2019

4 голосов
/ 19 ноября 2009

У меня проблема LNK2019 при попытке использовать некоторые DLL в моем проекте.

Детали:

  1. У меня есть проект DLL с именем dll1; это прекрасно скомпилировано (с использованием __declspec(dllexport)) для экспорта класса внутри dll1 (для использования dll2).
  2. У меня есть другой проект DLL dll2, который использует функциональность dll1. Я указал путь к файлу * .dll1.lib внутри входа компоновщика в свойствах проекта и дал ссылку на файлы dll1 * .h. На данный момент все должно работать нормально. (Я думаю ..)
  3. При компиляции dll2 я получаю ошибку LNK2019, которая говорит мне, что я не могу найти какой-то метод, на который ссылается dll1. (Этот метод в dll1 является статическим методом.)

Почему я получаю эту ошибку?

Ответы [ 4 ]

3 голосов
/ 19 ноября 2009

Страница MSDN о LNK2019 уже дает множество примеров, почему эта ошибка возникает. Чтобы отследить, что именно происходит, я рекомендую сделать следующее:

  1. Запустите undname на символе, на который жалуется компоновщик, чтобы разобрать имя (см. Просмотр украшенных имен , например, как запустить undname).
  2. Запустите dumpbin /EXPORTS (или используйте графический Dependency Walker ), чтобы получить список всех символов, экспортируемых DLL1.

Итак, теперь у вас есть выделенное имя символа, который пытается найти компоновщик, и у вас есть список символов, которые экспортируются DLL1. И компоновщик говорит вам, что он не может найти запрошенный символ в списке. Вот две идеи о том, что происходит:

  1. Вы видите, что DLL1 имеет деформированный символ в списке экспорта, но не точно искаженное имя, на которое жалуется компоновщик. Это может произойти, когда экспортируемая функция почти совпадает с ожидаемой компоновщиком. Возможно, у вас где-то отсутствует const, или соглашение о вызовах другое.
  2. Вы видите, что DLL1 не экспортирует символы, которые выглядят так, как ожидает компоновщик. Это говорит о том, что в объявлениях DLL1 отсутствует __declspec(dllexport).
2 голосов
/ 19 ноября 2009

Для обычных статических методов класса достаточно использовать declspec (dllexport), но в некоторых случаях (например, для встроенных функций-друзей) необходимо предоставить declspec (dllexport) для функции.

например.

#define DLLEXPORT __declspec(dllexport) 

class DLLEXPORT A {


     A();

     int somefunc();

     DLLEXPORT friend int operator==(const A &ws1, const A &ws2) 
            { /* some code */ } 

};   
1 голос
/ 19 ноября 2009

Просто предположение:

Если вы включите заголовок из dll1 в проект dll2 и в этом заголовке вы используете __declspec(dllexport)), вы сообщаете компоновщику, что dll2 также экспорт этих классов, которые на самом деле предназначены для импорта dll2 , поэтому отсутствует определение классов.

Так что обычно используют такое определение.

#ifdef DLL1_EXPORTS
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif

class DLLEXPORT A
{
    //...

Эта конструкция гарантирует, что определения dll1 экспортируются при использовании заголовка в dll1 и импортируются при использовании внутри проекта dll2 . Все, что вам нужно, это макрос DLL1_EXPORT, который будет определен при компиляции dll1 . Настройки проекта для dll1 - обычно хорошее место.

Другой подход состоит в том, чтобы иметь 2 разных заголовка, один для сборки dll1 и второй для совместного использования с dll1 lib (без каких-либо __declspec(dllexport)).

0 голосов
/ 20 сентября 2017

У меня недавно была такая же проблема. Проблема заключалась в сигнатуре метода void myMethod(const MyType&); с параметром, который я заранее объявил как class MyType;; однако, определение было struct MyType{};.

Как описано в https://stackoverflow.com/a/40738415/71051, это может привести к проблемам компоновщика с Visual-C ++ - в моем случае LNK2019.

Мне понадобилось время, чтобы решить эту проблему, возможно, это поможет кому-то в будущем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...