2010-08-31 51 views
1

我正在嘗試爲我正在處理的項目編寫一個調試類,並且我不希望必須傳遞一個調試對象,所以我試圖這樣做。但是,我不知道爲什麼我的編譯器或鏈接器似乎在跳過我爲它編寫的實現。調試類,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; 
} 

如果我在主函數中,我得到以下錯誤取消註釋打印線:

代碼:選擇所有

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 *,...)" ([email protected]@@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

+0

你是如何編譯這個的?它看起來好像你沒有編譯Debug.cpp代碼或正確鏈接它。 – easel 2010-08-31 02:14:03

+0

對不起,我仍在學習如何使用鏈接器。你能更具體一點嗎?我在一個解決方案中使用visual studio 2008編譯了兩個項目。一種解決方案,debug.cpp和debug.h作爲一個dll文件,主要作爲可執行文件。 – 2010-08-31 02:16:09

+0

我很久沒有與Visual Studio一起練習(「項目」?「解決方案」?),但它看起來好像它沒有鏈接到動態庫中。我建議你找到一個使用動態庫的HelloWorld「解決方案」,並確保你可以使它工作。 – Beta 2010-08-31 02:18:25

回答

0

Debug.cpp我相信你^ h在函數名稱上額外添加Debugger::限定符。改爲在cpp文件中嘗試使用void print(const char* fmt, ...)。該函數已包含在Debugger名稱空間中,不需要再次限定。

編輯:你實際上鍊接到最終的可執行文件Debug.o?如果你沒有將所有的目標文件鏈接到你的二進制文件中,你會得到像這樣的鏈接錯誤。與Java之類的運行時不同,C++無法神奇地確定從哪裏得到函數的定義,如print。你必須通過鏈接所有相應的文件來明確地告訴它。

+0

我試過這個,額外的限定詞似乎並不重要,因爲我得到相同的錯誤,或者沒有它。 – 2010-08-31 03:05:37

+0

「您是否真的將Debug.o鏈接到最終的可執行文件?」 不,我沒有。至少不是故意的。我不知道該怎麼做,我需要鏈接一個目標文件? – 2010-08-31 05:58:57