2010-08-31 4 views
1

J'essaie d'écrire une classe de débogage pour un projet sur lequel je travaille, et je ne veux pas avoir à passer un objet de débogage donc j'essayais de le faire de cette façon. Cependant, je ne sais pas pourquoi mon compilateur ou éditeur de liens semble ignorer l'implémentation que j'écris pour cela.Classe de débogage, C++, erreur de l'éditeur de liens

Si j'ajoute #include "Debug.cpp" à main.cpp, ce code fonctionne très bien. Le compilateur manque en quelque sorte l'implémentation des fonctions open, close et print à moins que je ne mette l'implémentation dans le fichier .h ou #include Debug.cpp.

Avez-vous une idée de la raison pour laquelle il ne voit pas l'implémentation dans Debug.cpp?

Je ne pense pas que ce soit important, mais actuellement debug.h et debug.cpp sont dans un projet et main.cpp est dans un autre projet (tous deux dans la même solution cependant, visual studio 2008). main.cpp est construit en tant qu'exécutable, et debug.h et debug.cpp sont compilés en tant que bibliothèque dynamique (dll).

Debug.h

Code: Tout sélectionner

#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: Tout sélectionner

#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: Sélectionner 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; 
} 

Si je Décommentez la ligne d'impression dans la fonction principale que je reçois l'erreur suivante:

Code: Tout sélectionner

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 

modifier: Un lien vers ma discussion originale:

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

+0

Comment compilez-vous cela? Il semble que vous ne compiliez pas le code Debug.cpp ou que vous ne le liez pas correctement. – easel

+0

Je suis désolé, j'apprends toujours à travailler avec l'éditeur de liens. Pourriez-vous être un peu plus précis? Je le compile avec Visual Studio 2008 avec deux projets dans une même solution. Une solution, le debug.cpp et debug.h en tant que fichier dll et le principal en tant qu'exécutable. –

+0

Je suis loin de la pratique avec Visual Studio ("project"? Solution "?), Mais il semble qu'il ne soit pas lié dans la bibliothèque dynamique. Je vous suggère de trouver une "solution" HelloWorld qui utilise une bibliothèque dynamique, et assurez-vous que cela fonctionne. – Beta

Répondre

0

En Debug.cpp Je vous crois h ave extra Debugger:: qualificateurs sur vos noms de fonctions. Essayez par exemple void print(const char* fmt, ...) dans le fichier cpp à la place. La fonction est déjà incluse dans l'espace de noms Debugger et n'a pas besoin d'être qualifiée à nouveau.

EDIT: Avez-vous réellement lier Debug.o dans l'exécutable final? Si vous ne liez pas dans tous les fichiers objets dans votre fichier binaire, vous obtiendrez des erreurs d'éditeur de liens comme ceci. Contrairement aux runtimes comme Java, C++ est incapable de déterminer de façon magique d'où obtenir une définition pour les fonctions telles que print. Vous devez le dire explicitement en liant dans tous les fichiers respectifs.

+0

J'ai essayé ceci, le qualificatif supplémentaire ne semble pas importer car j'obtiens la même erreur avec ou sans. –

+0

"Avez-vous réellement lié Debug.o dans l'exécutable final?" Non, je ne l'ai pas fait. Au moins pas intentionnellement. Je ne sais pas comment faire cela, j'ai besoin de lier un fichier objet? –