1

我正在尝试为我正在处理的项目编写一个调试类,并且我不想传递一个调试对象,所以我试图这样做。但是,我不知道为什么我的编译器或链接器似乎跳过了我正在为它编写的实现。

如果我将 #include "Debug.cpp" 添加到 main.cpp,则此代码可以正常工作。编译器不知何故缺少 open、close 和 print 函数的实现,除非我将实现放在 .h 文件或 #include Debug.cpp 中。

你知道为什么它没有在 Debug.cpp 中看到实现吗?

我认为这并不重要,但目前 debug.h 和 debug.cpp 在一个项目中,而 main.cpp 在另一个项目中(但都在同一个解决方案中,Visual Studio 2008)。main.cpp 正在构建为可执行文件,而 debug.h 和 debug.cpp 正在编译为动态库 (dll)。

调试.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

调试.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);
   }
}

主文件

代码:全选

#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

编辑:我原来讨论的链接:

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

4

1 回答 1

0

Debug.cpp相信您Debugger::的函数名称上有额外的限定符。例如void print(const char* fmt, ...)在 cpp 文件中尝试。该函数已包含在该Debugger名称空间中,无需再次限定。

编辑:你真的链接Debug.o到最终的可执行文件吗?如果你没有将所有目标文件链接到你的二进制文件中,你会得到像这样的链接器错误。与 Java 等运行时不同,C++ 无法神奇地确定从何处获取函数的定义,例如print. 您必须通过链接所有相应的文件来明确告诉它。

于 2010-08-31T02:26:07.447 回答