VS2008 не связан со всеми функциями в библиотеке - PullRequest
0 голосов
/ 29 сентября 2010

Наш проект основан на VS2008 и использует Boost и Qt.Однако сегодня у нас появилась новая проблема с линковкой, которая не имеет никакого смысла.

В результате происходит то, что во время ссылки

  • Для программы A наша статическая библиотека Foobar находитссылки на 5 из 8 функций-членов.
  • Для программы FoobarUnitTest все из Foobar связывается и работает нормально.
  • Для программы B наша библиотека Foobar2 представляет собой DLL.Во время ссылки он находит все функции-члены, кроме конструктора и деструктора.

Когда я говорю, что компоновщик находит некоторые функции-члены, то, что я сделал, было связано с параметром / VERBOSE.Затем я пошел и изучил полученный файл buildlog.htm и увидел, где компоновщик находит некоторые функции из библиотек.Ошибка компоновщика: `" ошибка LNK2019: неразрешенная внешняя "

Также то же самое происходит в 32-битном или 64-битном режиме - отладке или выпуске.

Есть предложения относительно того, где искать?

1 Ответ

0 голосов
/ 30 сентября 2010

Трудно дать какой-либо значимый совет для такого туманного вопроса, но вот пара вещей, которые нужно проверить. Компоновщик сообщает о «неразрешенных внешних», когда заголовок говорит, что есть функция с именем «x :: y ()», но он не может найти эту функцию в файле lib. Имейте в виду, что это предполагает, что вы действительно реализовали соответствующие функции. В конечном счете, как бы то ни было, проблема будет выглядеть так: «Вы сказали мне, что есть функция с именем x :: y (), но затем вы не реализовали функцию с именем x :: y ().»

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

На шаге 1 убедитесь, что вы declspec(__dllexport) используете функции в реализации библиотеки и declspec(__dllimport) используете функции на стороне клиента. Для этого я использую макросы:

MyFancyLib.h:

#ifndef MYLIB_API
#  define MYLIB_API (declspec(__dllimport))
#endif

MYLIB_API void DoIt();

MyFancyLib.CPP:

// this should be moved to stdafx.h or something sufficiently low-level
#define MYLIB_API (declspec(__dllexport))

MYLIB_API void DoIt()
{
  // magic happens
}

Шаг 2: Убедитесь, что вы действительно правильно назвали вещи в реализации. Одна из моих самых распространенных ошибок - объявить функцию-член класса или пространства имен, скажем, namespace Foo { void DoIt(); };, а затем забыть полностью определить класс или пространство имен в реализации. Если вы никогда не вызываете функцию в своей реализации, компоновщик может ее никогда не искать.

MyLib.h:

namespace lib
{
  MILIB_API void DoIt();
};

MyLib.cpp:

MYLIB_API void DoIt()
{
  // magic happens
};

Это создаст нерешенную внешнюю. CPP должен выглядеть так:

MyLibCorrect.cpp:

MYLIB_API void mylib::DoIt()
{
  // magic
}

Шаг 3: Убедитесь, что вы ссылаетесь на все, что вам нужно для ссылки. Это может показаться больше похожим на шаг-0 или шаг-1, но, если вы связались со всем, что, как вам кажется, 1032 * нужно, этот шаг может быть трудным. Посмотрите на имена, на которые жалуется компоновщик, сделайте некоторые из них и поищите код вашей библиотеки для реализации этих функций. Вы можете обнаружить, что они экспортированы из проекта, отличного от того, из которого, как вы думаете, они экспортируются.

...