Ошибки компоновщика одиночного кода в vc 9.0. Работает нормально в Linux, скомпилированном с GCC - PullRequest
0 голосов
/ 01 апреля 2010

У меня есть простой регистратор, который реализован как синглтон. Он работает так, как я хочу, когда я компилирую и запускаю его с g ++ в linux, но когда я компилирую в Visual Studio 9.0 с vc ++, я получаю следующие ошибки. Есть ли способ это исправить? Я не возражаю против изменения класса регистратора, но я хотел бы избежать изменения его названия.

1>Linking...
1>loggerTest.obj : error LNK2005: "public: static class Logger * __cdecl Logger::getInstance(void)" (?getInstance@Logger@@SAPAV1@XZ) already defined in Logger.obj
1>loggerTest.obj : error LNK2005: "public: void __thiscall Logger::log(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?log@Logger@@QAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) already defined in Logger.obj
1>loggerTest.obj : error LNK2005: "public: void __thiscall Logger::closeLog(void)" (?closeLog@Logger@@QAEXXZ) already defined in Logger.obj
1>loggerTest.obj : error LNK2005: "private: static class Logger * Logger::_instance" (?_instance@Logger@@0PAV1@A) already defined in Logger.obj
1>Logger.obj : error LNK2001: unresolved external symbol "private: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > Logger::_path" (?_path@Logger@@0V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A)
1>loggerTest.obj : error LNK2001: unresolved external symbol "private: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > Logger::_path" (?_path@Logger@@0V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A)
1>Logger.obj : error LNK2001: unresolved external symbol "private: static class boost::mutex Logger::_mutex" (?_mutex@Logger@@0Vmutex@boost@@A)
1>loggerTest.obj : error LNK2001: unresolved external symbol "private: static class boost::mutex Logger::_mutex" (?_mutex@Logger@@0Vmutex@boost@@A)
1>Logger.obj : error LNK2001: unresolved external symbol "private: static class std::basic_ofstream<char,struct std::char_traits<char> > Logger::_log" (?_log@Logger@@0V?$basic_ofstream@DU?$char_traits@D@std@@@std@@A)
1>loggerTest.obj : error LNK2001: unresolved external symbol "private: static class std::basic_ofstream<char,struct std::char_traits<char> > Logger::_log" (?_log@Logger@@0V?$basic_ofstream@DU?$char_traits@D@std@@@std@@A)

Код, три файла Logger.h Logger.cpp test.cpp

#ifndef __LOGGER_CPP__
#define __LOGGER_CPP__
#include "Logger.h"

Logger* Logger::_instance = 0;

//string Logger::_path = "log";
//ofstream Logger::_log;
//boost::mutex Logger::_mutex;

Logger* Logger::getInstance(){
  { 
    boost::mutex::scoped_lock lock(_mutex);
    if(_instance == 0) {
      _instance = new Logger;
   _path = "log";
    }
  } //mutex
  return _instance;
}


void Logger::log(const std::string& msg){
  {
    boost::mutex::scoped_lock lock(_mutex);
    if(!_log.is_open()){
      _log.open(_path.c_str());
    }
    if(_log.is_open()){
    _log << msg.c_str() << std::endl;
    }
  }
}

void Logger::closeLog(){
  Logger::_log.close();
}

#endif

`...

#ifndef __LOGGER_H__
#define __LOGGER_H__
#include <iostream>
#include <string>
#include <fstream>
#include <boost/thread/mutex.hpp>
#include <boost/thread.hpp>
using namespace std;

class Logger {
  public:
    static Logger* getInstance();
    void log(const std::string& msg);
    void closeLog();
  protected:
    Logger(){}
  private:
    static Logger* _instance;

    static string _path;
    static bool _logOpen;
    static ofstream _log;
    static boost::mutex _mutex; //check mutable
};
#endif

test.cpp `

#include <iostream>
#include "Logger.cpp"
using namespace std;
int main(int argc, char *argv[])
{
  Logger* log = Logger::getInstance();
  log->log("hello world\n");
  return 0;
}

Ответы [ 2 ]

2 голосов
/ 01 апреля 2010

Это проблема, поскольку вы определили символ несколько раз, скомпилировав CPP, а затем включив его в test.cpp ... По соглашению вы должны включать только объявление , а не определение как вы сделали.

Я удивлен, что gcc позволил бы кому-то быть настолько мягким в этом.

изменение

#include "Logger.cpp"

до

#include "Logger.h" 

и попробуй.

0 голосов
/ 01 апреля 2010

Проблема в том, что вы сделали #include "Logger.cpp" вместо #include "Logger.h" в test.cpp.Из-за этого символы внутри Logger.cpp будут определены несколько раз (один раз для модуля перевода logger.cpp и один раз для test.cpp).Наличие нескольких средств защиты от включения не помогает, потому что оно работает только внутри модуля перевода.

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