Hi,
I am using the SerializeElements template and specify 5 of them, each used to allow the serialization of classes I built. 4 of them compile fine but there is one that casues a
linking prolem that suggested that the template is defined in two different locations. Here
is the message:
SupaKewlDoc.obj : error LNK2005: "void __stdcall SerializeElements(class CArchive &,class IRCchannel * *,int)" (?SerializeElements@@YGXAAVCArchive@@PAPAVIRCchannel@@H@Z) already defined in IRCnetwork.obj
Debug/SupaKewl.exe : fatal error LNK1169: one or more multiply defined symbols found
Now the code compiles if I remove the template for the IRCchannel. Also I have done a find
for IRCchannel template elsewhere in the code and it definitely is only defined once.
I was thinking it maybe due to how the included statements are structured. I have included below the start code for the two files SupaKewlDoc and IRCnework. I'd appreciate any help or suggestions. Thanks a bunch.
// SupaKewlDoc.cpp : implementation of the CSupaKewlDoc class
//
#include "stdafx.h"
#include "SupaKewl.h"
#include
#include
#include
#include "SupaKewlDoc.h"
#include "ircnetwork.h"
#include "ircsocket.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CSupaKewlDoc
IMPLEMENT_DYNCREATE(CSupaKewlDoc, CDocument)
BEGIN_MESSAGE_MAP(CSupaKewlDoc, CDocument)
ON_COMMAND(ID_FILE_SAVE, OnFileSave)
ON_COMMAND(ID_FILE_RESET, ResetState)
END_MESSAGE_MAP()
/////////// SERIALIZATION STUFF ///////////////////
template <> void AFXAPI SerializeElements ( CArchive& ar, IRCnetwork** pItem, int nCount )
{
for ( int i = 0; i < nCount; i++, pItem++ )
{
(*pItem)->Serialize( ar );
}
}
template <> void AFXAPI SerializeElements ( CArchive& ar, DCCserver** pItem, int nCount )
{
for ( int i = 0; i < nCount; i++, pItem++ )
{
(*pItem)->Serialize( ar );
}
}
template <> void AFXAPI SerializeElements ( CArchive& ar, DCCfile** pItem, int nCount )
{
for ( int i = 0; i < nCount; i++, pItem++ )
{
(*pItem)->Serialize( ar );
}
}
template <> void AFXAPI SerializeElements ( CArchive& ar, IRCchannel** pItem, int nCount )
{
for ( int i = 0; i < nCount; i++, pItem++ )
{
(*pItem)->Serialize( ar );
}
}
// CSupaKewlDoc construction/destruction
CSupaKewlDoc::CSupaKewlDoc()
{
// TODO: add one-time construction code he
this->SetTitle("hello"
;
}
CSupaKewlDoc::~CSupaKewlDoc()
{
//////////////////////////////////////
// remove all files
//////////////////////////////////////
DCCfile *dccFile = NULL;
for (int nFiles = 0; nFiles < m_DCCfiles.GetCount(); nFiles++)
{
dccFile = m_DCCfiles.ElementAt(nFiles);
delete dccFile;
}
m_DCCfiles.RemoveAll();
m_DCCfiles.FreeExtra();
... rest of the code not included...
#include "StdAfx.h"
#include "ircnetwork.h"
/////////// SERIALIALIZATION ////////////////////
IMPLEMENT_SERIAL(IRCnetwork,CObject,1)
IMPLEMENT_SERIAL(IRCserver,CObject,1)
IMPLEMENT_SERIAL(DCCserver,CObject,1)
IMPLEMENT_SERIAL(DCCfile,CObject,1)
IMPLEMENT_SERIAL(IRCchannel,CObject,1)
template <> void AFXAPI SerializeElements ( CArchive& ar, IRCserver** pItem, int nCount )
{
for ( int i = 0; i < nCount; i++, pItem++ )
{
(*pItem)->Serialize( ar );
}
}
//////////// IRC NETWORK CLASS ////////////////
IRCnetwork::IRCnetwork()
{
}
IRCnetwork::~IRCnetwork()
{
IRCserver *networkServer = NULL;
for (int nServers = 0; nServers < serverNetwork.GetCount(); nServers++)
{
networkServer = serverNetwork.ElementAt(nServers);
delete networkServer;
}
serverNetwork.RemoveAll();
serverNetwork.FreeExtra();
IRCchannel *networkChannel = NULL;
for (int nChannels = 0; nChannels < channelArray.GetCount(); nChannels++)
{
networkChannel = channelArray.ElementAt(nChannels);
delete networkChannel;
}
channelArray.RemoveAll();
channelArray.FreeExtra();
}
IRCnetwork::IRCnetwork(CString name)
{
networkName = name;
}
void IRCnetwork::addServer(IRCserver *newIRCserver)
{
serverNetwork.Add(newIRCserver);
}
CString IRCnetwork::GetName()
{
return networkName;
}
void IRCnetwork::Serialize(CArchive& ar)
{
CObject::Serialize( ar );
serverNetwork.Serialize(ar);
channelList.Serialize(ar);
channelArray.Serialize(ar);
/*CString networkName;
CArray serverNetwork;
CStringList channelList;
CArray channelArray;*/
if (ar.IsStoring())
ar << networkName;// << currentInChannel << channelActivity;
else
ar >> networkName;// >> currentInChannel >> channelActivity;
}
I am using the SerializeElements template and specify 5 of them, each used to allow the serialization of classes I built. 4 of them compile fine but there is one that casues a
linking prolem that suggested that the template is defined in two different locations. Here
is the message:
SupaKewlDoc.obj : error LNK2005: "void __stdcall SerializeElements(class CArchive &,class IRCchannel * *,int)" (?SerializeElements@@YGXAAVCArchive@@PAPAVIRCchannel@@H@Z) already defined in IRCnetwork.obj
Debug/SupaKewl.exe : fatal error LNK1169: one or more multiply defined symbols found
Now the code compiles if I remove the template for the IRCchannel. Also I have done a find
for IRCchannel template elsewhere in the code and it definitely is only defined once.
I was thinking it maybe due to how the included statements are structured. I have included below the start code for the two files SupaKewlDoc and IRCnework. I'd appreciate any help or suggestions. Thanks a bunch.
// SupaKewlDoc.cpp : implementation of the CSupaKewlDoc class
//
#include "stdafx.h"
#include "SupaKewl.h"
#include
#include
#include
#include "SupaKewlDoc.h"
#include "ircnetwork.h"
#include "ircsocket.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CSupaKewlDoc
IMPLEMENT_DYNCREATE(CSupaKewlDoc, CDocument)
BEGIN_MESSAGE_MAP(CSupaKewlDoc, CDocument)
ON_COMMAND(ID_FILE_SAVE, OnFileSave)
ON_COMMAND(ID_FILE_RESET, ResetState)
END_MESSAGE_MAP()
/////////// SERIALIZATION STUFF ///////////////////
template <> void AFXAPI SerializeElements ( CArchive& ar, IRCnetwork** pItem, int nCount )
{
for ( int i = 0; i < nCount; i++, pItem++ )
{
(*pItem)->Serialize( ar );
}
}
template <> void AFXAPI SerializeElements ( CArchive& ar, DCCserver** pItem, int nCount )
{
for ( int i = 0; i < nCount; i++, pItem++ )
{
(*pItem)->Serialize( ar );
}
}
template <> void AFXAPI SerializeElements ( CArchive& ar, DCCfile** pItem, int nCount )
{
for ( int i = 0; i < nCount; i++, pItem++ )
{
(*pItem)->Serialize( ar );
}
}
template <> void AFXAPI SerializeElements ( CArchive& ar, IRCchannel** pItem, int nCount )
{
for ( int i = 0; i < nCount; i++, pItem++ )
{
(*pItem)->Serialize( ar );
}
}
// CSupaKewlDoc construction/destruction
CSupaKewlDoc::CSupaKewlDoc()
{
// TODO: add one-time construction code he
this->SetTitle("hello"
}
CSupaKewlDoc::~CSupaKewlDoc()
{
//////////////////////////////////////
// remove all files
//////////////////////////////////////
DCCfile *dccFile = NULL;
for (int nFiles = 0; nFiles < m_DCCfiles.GetCount(); nFiles++)
{
dccFile = m_DCCfiles.ElementAt(nFiles);
delete dccFile;
}
m_DCCfiles.RemoveAll();
m_DCCfiles.FreeExtra();
... rest of the code not included...
#include "StdAfx.h"
#include "ircnetwork.h"
/////////// SERIALIALIZATION ////////////////////
IMPLEMENT_SERIAL(IRCnetwork,CObject,1)
IMPLEMENT_SERIAL(IRCserver,CObject,1)
IMPLEMENT_SERIAL(DCCserver,CObject,1)
IMPLEMENT_SERIAL(DCCfile,CObject,1)
IMPLEMENT_SERIAL(IRCchannel,CObject,1)
template <> void AFXAPI SerializeElements ( CArchive& ar, IRCserver** pItem, int nCount )
{
for ( int i = 0; i < nCount; i++, pItem++ )
{
(*pItem)->Serialize( ar );
}
}
//////////// IRC NETWORK CLASS ////////////////
IRCnetwork::IRCnetwork()
{
}
IRCnetwork::~IRCnetwork()
{
IRCserver *networkServer = NULL;
for (int nServers = 0; nServers < serverNetwork.GetCount(); nServers++)
{
networkServer = serverNetwork.ElementAt(nServers);
delete networkServer;
}
serverNetwork.RemoveAll();
serverNetwork.FreeExtra();
IRCchannel *networkChannel = NULL;
for (int nChannels = 0; nChannels < channelArray.GetCount(); nChannels++)
{
networkChannel = channelArray.ElementAt(nChannels);
delete networkChannel;
}
channelArray.RemoveAll();
channelArray.FreeExtra();
}
IRCnetwork::IRCnetwork(CString name)
{
networkName = name;
}
void IRCnetwork::addServer(IRCserver *newIRCserver)
{
serverNetwork.Add(newIRCserver);
}
CString IRCnetwork::GetName()
{
return networkName;
}
void IRCnetwork::Serialize(CArchive& ar)
{
CObject::Serialize( ar );
serverNetwork.Serialize(ar);
channelList.Serialize(ar);
channelArray.Serialize(ar);
/*CString networkName;
CArray serverNetwork;
CStringList channelList;
CArray channelArray;*/
if (ar.IsStoring())
ar << networkName;// << currentInChannel << channelActivity;
else
ar >> networkName;// >> currentInChannel >> channelActivity;
}