0
votes

PacketBuilder is a little Class which allow to write into a char* array. The Append Functions:

template <class T>
void PacketBuilder::Append(const T value)
{
 memcpy((&m_Buffer) + m_Index, (const void*) &value, sizeof(T));
 m_Index += sizeof(T);
}

Compiling without errors. If I call Append and use T as unsigned short (WORD). It works great. If I use T as unsigned char. I get an Linker Error.

m_Builder.Append<unsigned char>(0x01); // Error: LNK1120
m_Builder.Append<unsigned short>(0x0001); // Works

Error from VS2010 (sry i got german vs2010):

error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: void __thiscall PacketBuilder::Append(unsigned char)" (??$Append@E@PacketBuilder@@QAEXE@Z)" in Funktion ""public: void __thiscall Client::DoHandshake(void)" (?DoHandshake@Client@@QAEXXZ)". 1>C:\XXX\C++\SilkroadEmu\Debug\LoginServer.exe : fatal error LNK1120: 1 nicht aufgelöste externe Verweise.

Translated to English:

error LNK2019: Unresolved external symbol ""public: void __thiscall PacketBuilder::Append(unsigned char)" (??$Append@E@PacketBuilder@@QAEXE@Z)" in Function ""public: void __thiscall Client::DoHandshake(void)" (?DoHandshake@Client@@QAEXXZ)". 1>C:\XXX\C++\SilkroadEmu\Debug\LoginServer.exe : fatal error LNK1120: 1 unsresolved external symbol.

2
Can you add the actual linker error messages to your question? - Oliver Charlesworth
LNK1120 only tells you the number of unresolved externals. You need to post the entire linker error message, including all the LNK2001 messages that come before the LNK1120 message. Just telling us the error code is not enough, as there are many, many causes of a LNK2001 error. If those error messages refer to code that's not part of your question, you should add a minimal code snippet of those as well. - In silico
I can only guess what the problem is given the current information, but perhaps these will be of help: parashift.com/c++-faq-lite/templates.html#faq-35.12 and parashift.com/c++-faq-lite/templates.html#faq-35.13. - Oliver Charlesworth

2 Answers

5
votes

Put the method definition in the header (hpp file), not in the implementation (cpp) file.

1
votes

Your PacketBuilder is not a class template, as far as I can see. PacketBuilder::Append is however a template method, which requires that it's definition must be visible at any point of instantiation of this method. The only really safe way to assure this is to put the complete definition of this method template into the header file:

class PacketBuilder {
 // declarations of non-template members

public:
 template <class T> 
 void Append(const T value) 
 { 
  memcpy((&m_Buffer) + m_Index, (const void*) &value, sizeof(T)); 
  m_Index += sizeof(T); 
 }

};