调试类,c++,链接器错误
我正在尝试为我正在处理的项目编写一个调试类,并且我不想传递调试对象,所以我尝试这样做。但是,我不知道为什么我的编译器或链接器似乎跳过我为其编写的实现。
如果我将 #include "Debug.cpp" 添加到 main.cpp 中,此代码就可以正常工作。编译器在某种程度上缺少打开、关闭和打印函数的实现,除非我将实现放入 .h 文件或 #include Debug.cpp。
您知道为什么在 Debug.cpp 中看不到实现吗?
我认为这并不重要,但目前 debug.h 和 debug.cpp 位于一个项目中,而 main.cpp 位于另一个项目中(但两者都在同一解决方案中,Visual Studio 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;
}
如果我取消注释 main 函数中的打印行,则会出现以下错误:
代码:全选
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
I am trying to write a debug class for a project I am working on, and I do not want to have to pass a debug object around so I was trying to do it this way. However, I do not know why my compiler or linker seems to be skipping the implementation I am writing for it.
If I add #include "Debug.cpp" to main.cpp this code works just fine. The compiler is somehow missing the implementation of the open, close, and print functions unless I either put the implementation in the .h file or #include Debug.cpp.
Do you have any idea why it is not seeing the implementation in Debug.cpp?
I do not think it matters, but currently debug.h and debug.cpp are in one project and main.cpp is in another project (both within the same solution however, visual studio 2008). main.cpp is being built as an executable, and debug.h and debug.cpp are being compiled as a dynamic library (dll).
Debug.h
Code: Select all
#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
Code: Select all
#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
Code: Select all
#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;
}
If I un-comment the print line in the main function I get the following error:
Code: Select all
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: A link to my original discussion:
http://elysianshadows.com/phpBB3/viewtopic.php?f=6&t=5328&start=999999
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 Debug.cpp 中,我相信您的函数名称上有额外的 Debugger:: 限定符。例如尝试在 cpp 文件中使用
void print(const char* fmt, ...)
。该函数已包含在 Debugger 命名空间中,无需再次限定。编辑:您实际上是否将 Debug.o 链接到最终的可执行文件中?如果您不将所有目标文件链接到二进制文件中,您将收到类似这样的链接器错误。与 Java 等运行时不同,C++ 无法神奇地确定从何处获取 print 等函数的定义。您必须通过链接所有相应的文件来明确地告诉它。
In
Debug.cpp
I believe you have extraDebugger::
qualifiers on your function names. Try for examplevoid print(const char* fmt, ...)
in the cpp file instead. The function is already enclosed in theDebugger
namespace there and need not be qualified again.EDIT: Did you actually link
Debug.o
into the final executable? If you don't link in all the object files into your binary, you'll get linker errors like this. Unlike runtimes like Java, C++ is unable to magically determine from where to get a definition for functions such asprint
. You have to explicitly tell it by linking in all the respective files.