Класс отладки, c ++, ошибка компоновщика - PullRequest
1 голос
/ 31 августа 2010

Я пытаюсь написать класс отладки для проекта, над которым я работаю, и я не хочу передавать объект отладки, поэтому я пытался сделать это таким образом.Однако я не знаю, почему мой компилятор или компоновщик пропускает реализацию, которую я пишу для него.

Если я добавлю #include "Debug.cpp" в main.cpp, этот код будет работать нормально.Компилятору почему-то не хватает реализации функций открытия, закрытия и печати, если я не помещу реализацию в файл .h или #include Debug.cpp.

У вас есть идеи, почему он не видитреализация в Debug.cpp?

Я не думаю, что это имеет значение, но в настоящее время debug.h и debug.cpp находятся в одном проекте, а main.cpp - в другом проекте (оба в одном решении, однако визуальностудия 2008).main.cpp создается как исполняемый файл, а debug.h и debug.cpp компилируются как динамическая библиотека (dll).

Debug.h

Код: выбрать все

#define BUFFER_SIZE 1028
#include <string>
#include <fstream>
#include <assert.h>
#include <stdarg.h> // va_arg

#ifndef _DEBUG_H_
#define _DEBUG_H_
namespace Debugger
{
   // member variables
   extern const unsigned int m_sizebuffer;
   extern std::ofstream m_file;
   extern bool m_fileopened;
   extern char m_buffer[BUFFER_SIZE];
   extern va_list m_vl;

   /*
      'extern' keyword there to remind myself that
      all functions are implicitly extern, so
      declaring variables with 'extern' is more intuitive.
      Will remove when the 'extern' keyword becomes second nature to me.
   */
   extern void open_file();
   extern void close_file();
   extern void print(const char* fmt, ...);
}

#endif

Debug.cpp

Код: выбрать все

#ifndef _DEBUG_H_
#include "Debug.h"
#endif

namespace Debugger
{
   const unsigned int m_sizebuffer = BUFFER_SIZE;
   std::ofstream m_file;
   bool m_fileopened;
   char m_buffer[BUFFER_SIZE];
   va_list m_vl;

   void Debugger::open_file()
   {
      // file cannot already be opened.
      assert(!m_fileopened);
      m_file.clear(); // clear contents of debug file.

      //if directory already exists nothing *SHOULD* happen. platform dependent.
      system("mkdir Data");

      m_file.open("./Data/ErrorLog.txt");   // hard-coding filename is intentional
      if(m_file.is_open() )
      {
         m_fileopened = true;
         print("Debug: successfully loaded file './Data/ErrorLog.txt' \n" );
      }
   }

   void Debugger::close_file()
   {
      if(m_fileopened)
      {
         m_file.close();
         m_fileopened = false;
      }
   }

   /*
      WARNING: Should only accept c-style strings only. If output is ever cryptic double check
      that we are not passing c++ Strings instead of char*, do not know how to differentiate if
      fmt is a c-style string (char*) or a C++ String.
   */
   void Debugger::print(const char* fmt, ...)
   {
      if(!m_fileopened)
      {
         open_file();
         print("Debug file opened. \n");
      }
      int retval = 0;

      va_start(m_vl, fmt);
      retval = vsnprintf_s(m_buffer, m_sizebuffer, m_sizebuffer, fmt, m_vl);
      va_end(m_vl);
      m_file << m_buffer;
      m_file.flush();

      assert(retval > 0);
   }
}

main.cpp

Код: выбрать все

#include "stdlib.h"
#ifndef _DEBUG_H_
#include "Debug.h"
#endif

int main(int argc, char* argv[])
{
   //Debugger::print("this should work~! yay");

   return EXIT_SUCCESS;
}

Если я откомментирую строку печати в основной функции, я получаю следующую ошибку:

Код: Выбрать все

1>LINK : C:\Users\Benjamin\Desktop\vs projects (c++)\Game Debugger\debug class\Debug\Smashteroids.exe not found or not built by the last incremental link; performing full link
1>main.obj : error LNK2019: unresolved external symbol "void __cdecl Debugger::print(char const *,...)" (?print@Debugger@@YAXPBDZZ) referenced in function _main
1>C:\Users\Benjamin\Desktop\vs projects (c++)\Game Debugger\debug class\Debug\Smashteroids.exe : fatal error LNK1120: 1 unresolved externals

edit: ссылка на мое исходное обсуждение:

http://elysianshadows.com/phpBB3/viewtopic.php?f=6&t=5328&start=999999

1 Ответ

0 голосов
/ 31 августа 2010

В Debug.cpp Я полагаю, у вас есть дополнительные квалификаторы Debugger:: в именах ваших функций. Попробуйте, например, void print(const char* fmt, ...) в файле cpp. Функция уже заключена в пространство имен Debugger и не нуждается в повторном уточнении.

РЕДАКТИРОВАТЬ: Вы действительно связали Debug.o в окончательный исполняемый файл? Если вы не добавите ссылки на все объектные файлы в свой двоичный файл, вы получите ошибки компоновщика, подобные этой. В отличие от сред выполнения, подобных Java, C ++ не может волшебным образом определить, откуда получить определение для таких функций, как print. Вы должны явно указать это, связав все соответствующие файлы.

...