0

I modified an existing class in my visual C++ application to make it a generic class. This class is used by two other modules. When I compile these modules separately everything works. However, when I do a Build All, I get these linker errors:

1>Linking...
1>   Creating library C:\ccmdb\prep\g3_v5.3\g3_tools\fc_tools\ZFRTool\ZStackMTI\Debug\ZStackMTI.lib and object C:\ccmdb\prep\g3_v5.3\g3_tools\fc_tools\ZFRTool\ZStackMTI\Debug\ZStackMTI.exp
1>SerialPort.obj : error LNK2019: unresolved external symbol "public: __thiscall CRingBuffer<unsigned char>::CRingBuffer<unsigned char>(unsigned long)" (??0?$CRingBuffer@E@@QAE@K@Z) referenced in function "public: __thiscall CSerialPort::CSerialPort(void)" (??0CSerialPort@@QAE@XZ)
1>ZStackMTI.obj : error LNK2001: unresolved external symbol "public: __thiscall CRingBuffer<unsigned char>::CRingBuffer<unsigned char>(unsigned long)" (??0?$CRingBuffer@E@@QAE@K@Z)
1>SerialPort.obj : error LNK2019: unresolved external symbol "public: __thiscall CRingBuffer<unsigned char>::~CRingBuffer<unsigned char>(void)" (??1?$CRingBuffer@E@@QAE@XZ) referenced in function "public: void * __thiscall CRingBuffer<unsigned char>::`scalar deleting destructor'(unsigned int)" (??_G?$CRingBuffer@E@@QAEPAXI@Z)
1>ZStackMTI.obj : error LNK2001: unresolved external symbol "public: __thiscall CRingBuffer<unsigned char>::~CRingBuffer<unsigned char>(void)" (??1?$CRingBuffer@E@@QAE@XZ)
1>SerialPort.obj : error LNK2019: unresolved external symbol "public: unsigned long __thiscall CRingBuffer<unsigned char>::GetBufferItems(void)" (?GetBufferItems@?$CRingBuffer@E@@QAEKXZ) referenced in function "public: unsigned long __thiscall CSerialPort::GetBufferedRxItems(void)" (?GetBufferedRxItems@CSerialPort@@QAEKXZ)
1>SerialPort.obj : error LNK2019: unresolved external symbol "public: int __thiscall CRingBuffer<unsigned char>::Peek(unsigned char *,unsigned long,unsigned long *)" (?Peek@?$CRingBuffer@E@@QAEHPAEKPAK@Z) referenced in function "public: unsigned long __thiscall CSerialPort::Peek(unsigned char *,unsigned long,unsigned long *)" (?Peek@CSerialPort@@QAEKPAEKPAK@Z)
1>SerialPort.obj : error LNK2019: unresolved external symbol "public: int __thiscall CRingBuffer<unsigned char>::Remove(unsigned char *,unsigned long,unsigned long *)" (?Remove@?$CRingBuffer@E@@QAEHPAEKPAK@Z) referenced in function "public: unsigned long __thiscall CSerialPort::Read(unsigned char *,unsigned long,unsigned long *)" (?Read@CSerialPort@@QAEKPAEKPAK@Z)
1>ZStackMTI.obj : error LNK2001: unresolved external symbol "public: int __thiscall CRingBuffer<unsigned char>::Remove(unsigned char *,unsigned long,unsigned long *)" (?Remove@?$CRingBuffer@E@@QAEHPAEKPAK@Z)
1>SerialPort.obj : error LNK2019: unresolved external symbol "public: int __thiscall CRingBuffer<unsigned char>::Add(unsigned char *,unsigned long,int)" (?Add@?$CRingBuffer@E@@QAEHPAEKH@Z) referenced in function "public: unsigned long __thiscall CSerialPort::Write(unsigned char *,unsigned long)" (?Write@CSerialPort@@QAEKPAEK@Z)
1>ZStackMTI.obj : error LNK2001: unresolved external symbol "public: int __thiscall CRingBuffer<unsigned char>::Add(unsigned char *,unsigned long,int)" (?Add@?$CRingBuffer@E@@QAEHPAEKH@Z)
1>SerialPort.obj : error LNK2019: unresolved external symbol "public: int __thiscall CRingBuffer<unsigned char>::Delete(unsigned long)" (?Delete@?$CRingBuffer@E@@QAEHK@Z) referenced in function "public: unsigned long __thiscall CSerialPort::Delete(unsigned long,int)" (?Delete@CSerialPort@@QAEKKH@Z)
1>SerialPort.obj : error LNK2019: unresolved external symbol "public: int __thiscall CRingBuffer<unsigned char>::Flush(void)" (?Flush@?$CRingBuffer@E@@QAEHXZ) referenced in function "public: unsigned long __thiscall CSerialPort::Flush(int)" (?Flush@CSerialPort@@QAEKH@Z)
1>ZStackMTI.obj : error LNK2019: unresolved external symbol "public: unsigned char __thiscall CRingBuffer<unsigned char>::Peek(unsigned long)" (?Peek@?$CRingBuffer@E@@QAEEK@Z) referenced in function "unsigned long __cdecl ZBNConnect_GetExtAddr(unsigned char *)" (?ZBNConnect_GetExtAddr@@YAKPAE@Z)
1>C:\ccmdb\prep\g3_v5.3\g3_tools\fc_tools\ZFRTool\ZStackMTI\Debug\ZStackMTI.dll : fatal error LNK1120: 9 unresolved externals
1>Build log was saved at "file://c:\ccmdb\prep\g3_v5.3\g3_tools\fc_tools\ZFRTool\ZStackMTI\ZStackMTI\Debug\BuildLog.htm"
1>ZStackMTI - 14 error(s), 0 warning(s)

I am using Visual Studio 2008. Does anyone know how to fix this? Prior to the modifications, everything built and linked without any problems. Thanks.

Jim Fell
  • 13,750
  • 36
  • 127
  • 202

2 Answers2

7

Implement your template functions in the header file.

The compiler needs to see the entire class template when it creates an actual class from the template. See e.g. Why should the implementation and the declaration of a template class be in the same header file?

Community
  • 1
  • 1
Erik
  • 88,732
  • 13
  • 198
  • 189
  • How will that fix the problem? – Jim Fell Mar 08 '11 at 19:11
  • A template class is *not* a class, it is a *template*. When the compiler see you using `Foo` it creates an actual class from the template code. If the compiler can only see a `Foo` member function *declaration* when it creates this class, it will only create a `Foo` member function declaration. If it can see the definition, it will also create a definition. – Erik Mar 08 '11 at 19:14
  • Should I cut & past the template function definitions to the end of the header file, where the template class is defined? Or, do they actually need to be nested within the class, similar to how Java or C# classes are defined? – Jim Fell Mar 08 '11 at 19:19
  • That's your choice, both will work. Personally I prefer to have them inline in the class. – Erik Mar 08 '11 at 19:20
  • Thanks for the help. It compiled and linked successfully. It'll be interesting to see the comments I receive in my next code review. – Jim Fell Mar 08 '11 at 19:27
0

This can be because the linker can't find the method bodies of your concrete class.

One workaround is to include the actual .cpp file instead of the .h file when you use declare the concrete instances of your templated classes.

Jimmy
  • 6,001
  • 1
  • 22
  • 21