2014-12-15 2 views
0

Я получаю эту ошибку от линкера:Почему «неразрешенный внешний символ» в VS2010 (lnk2001), когда символ определен в .lib? C++, подталкивание, cpputest

1>PACBalancesTest.obj : error LNK2001: unresolved external symbol "public: bool __thiscall PAC::BalChgKeyComparator::operator()(class PAC::BalChgKey const &,class PAC::BalChgKey const &)const " ([email protected]@@[email protected]@[email protected]) 

Я должен отсутствовать что-то действительно очевидное, потому что я смотрел на определение символа «отсутствующей» неоднократно и может» Нет проблем.

Определение символа находится в файле .lib. Я вижу следующие на выходе из Dumpbin/символов на этом .lib файл:

2F0 00000000 SECTFD notype() External  | [email protected]@@[email protected]@[email protected] (public: bool __thiscall PAC::BalChgKeyComparator::operator()(class PAC::BalChgKey const &,class PAC::BalChgKey const &)const) 

Есть и другие символы, успешно решаются с этого .lib файл! (Фактически, из того же .obj.) [Обновление: я больше не думаю, что предыдущее утверждение верно. Это может быть моя первая попытка доступа к любой функции, не определенной в файле .h.]

ЧТО ПОСЛЕДУЮЩИЕ НЕ СООТВЕТСТВУЮТ ПРОБЛЕМЕ - ТАК ПОЖАЛУЙСТА, НЕ ПОСЫЛАЙТЕ ВРЕМЯ ИЗУЧЕНИЕ ЭТОГО!

Вот объявление функции (в PACBalances.h):

namespace PAC { 
    class BalChgKey { 
    public: 
     ... 
    }; 

    struct BalChgKeyComparator { 
     bool operator()(const BalChgKey& lhs, const BalChgKey& rhs) const; 
    }; 

    typedef std::multimap<BalChgKey, long, BalChgKeyComparator> BalChgKeyLongMMap; 
}; 

Обратите внимание, что я попытался изменить «-структуру» выше «класс», без эффекта.

Вот код вызова (в тестовом файле cpputest):

#include "CppUTest/TestHarness.h" 

#include <utility> 
#include <map> 
#include "PACBalances.h" 

using namespace PAC; 

... 

TEST_GROUP(PACBalanceCUMap) 
{ 
    BalChgKeyLongMMap empty; 
    BalChgKeyLongMMap onesy; 

    void setup() 
    { 
     // **Adding the following line caused this error to start to occur.** 
     onesy.insert(std::pair<BalChgKey, long>(BalChgKey(BOPCAT_FEE, PAYMTYPE_OVERDRAFT_FEE, 4321, 41100, 1, 17), 17)); 
    } 
    void breakdown() 
    { 
    } 
}; 

А вот определение самой функции оператора:

bool PAC::BalChgKeyComparator::operator()(
    const BalChgKey& thing1, 
    const BalChgKey& thing2 
    ) const 
{ 
    if (thing1.m_balKey.m_balCat < thing2.m_balKey.m_balCat)  return true; 
    else if (thing1.m_balKey.m_balCat > thing2.m_balKey.m_balCat) return false; 
    // Fall thru if balCats are equal 
    ... 
    return false; 
} 

Пожалуйста, обратите внимание, что:

  1. Компаратор и мультиплекс typedef'd прекрасно работают с большим количеством кода (не показано выше).
  2. В тестовом файле много других функций, объявленных и определенных в этом файле .h, но это первый раз, когда я попытался вызвать функцию, определенную в отдельном файле .cpp.
  3. Мой вопрос: не Почему для вызова «onesy.insert» требуется функция компаратора. Я это понимаю. Это просто первая операция мультимапа, которую я закодировал в тестовом наборе, который фактически использует компаратор.

У меня разные возможности, но я убегаю от них, поэтому, если кто-то, кто знает об этом, может дать мне какие-либо выводы, я был бы очень благодарен.

Norm

+0

Является исходным файлом, в котором 'operator()' определен частью проекта MSVC? То есть, знает ли MSVC, что он должен компилировать и связывать его? – Wintermute

+1

И вы действительно связали этот блок компиляции, который содержит определение 'PAC :: BalChgKeyComparator :: operator()'? –

+0

@Wintermute: Да, и он действительно компилирует его и создает .lib-файл, содержащий его объект. –

ответ

0

@panta рей: Вы дали ключ в ваш комментарий. (Извините, не могу понять, как набирать греческие буквы здесь.)

Проблема была в основном в том, что я не знал, как сообщить Visual Studio, к каким объектам подключиться. Я сказал свое решение, которое AnalyticsUTest зависело от AnalysticsUTested, но шаг связывания выполняется проектом (AnalyticsUTest), а не решением, поэтому мне нужно сказать проекту, чтобы он включал этот .lib-файл.

Итак, я перешел на страницу свойств проекта и создал два новых макроса, один из которых предоставил папку, в которой VS помещал мой .lib-файл (ANALYTICSUTEDED_LIB_PATHS), а другой - имя моего .lib-файла (ANALYTICSUTEDED_LIB_DEPENDENCIES) - оба по аналогии с макросами CPPUTEST_LIB *.

И затем я добавил $ (ANALYTICSUTESTED_LIB_PATHS) в Linker> General> Дополнительные библиотечные каталоги. И я добавил $ (ANALYTICSUTESTED_LIB_DEPENDENCIES) в Linker> Input> Additional Dependencies.

И это исправило мою проблему! (Я прописал это здесь, в случае, если сюда приходит еще один новичок, и мне это нужно.)

Спасибо, panta rei. Как я могу дать вам баллы за ответ, предоставленный через комментарий?

Смежные вопросы