title: Debug class, c++, linker error
body: <p>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. </p>
  
  <p>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.</p>
  
  <p>Do you have any idea why it is not seeing the implementation in Debug.cpp?</p>
  
  <p>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).</p>
  
  <p>Debug.h</p>
  
  <p>Code: Select all</p>
  
  <pre><code>#define BUFFER_SIZE 1028
  #include &lt;string&gt;
  #include &lt;fstream&gt;
  #include &lt;assert.h&gt;
  #include &lt;stdarg.h&gt; // 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
  </code></pre>
  
  <p>Debug.cpp</p>
  
  <p>Code: Select all</p>
  
  <pre><code>#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 &lt;&lt; m_buffer;
        m_file.flush();
  
        assert(retval &gt; 0);
     }
  }
  </code></pre>
  
  <p>main.cpp</p>
  
  <p>Code: Select all</p>
  
  <pre><code>#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;
  }
  </code></pre>
  
  <p>If I un-comment the print line in the main function I get the following error:</p>
  
  <p>Code: Select all</p>
  
  <pre><code>1&gt;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&gt;main.obj : error LNK2019: unresolved external symbol "void __cdecl Debugger::print(char const *,...)" (?print@Debugger@@YAXPBDZZ) referenced in function _main
  1&gt;C:\Users\Benjamin\Desktop\vs projects (c++)\Game Debugger\debug class\Debug\Smashteroids.exe : fatal error LNK1120: 1 unresolved externals
  </code></pre>
  
  <p>edit: A link to my original discussion:</p>
  
  <p><a href="http://elysianshadows.com/phpBB3/viewtopic.php?f=6&amp;t=5328&amp;start=999999" rel="nofollow noreferrer">http://elysianshadows.com/phpBB3/viewtopic.php?f=6&amp;t=5328&amp;start=999999</a></p>