Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to use DumpElements

Status
Not open for further replies.

sschantz

Programmer
Aug 10, 2001
9
CA
Hi,
I try to use the DumpElements function to dump specific
information from a CMap declared in has a member of a Class. If I define the Dump function
has follow in CPP:
template <> void AFXAPI DumpElements<CString>
(CDumpContext& dc, const CString* pElements, INT_PTR
nCount)
{
. do something
}
I get a linker error (LNK2005) that this function is
already defined in a other obj. The only thing defined in
this obj is a other CMap of CStrig has class member.

Is there any sample available on you to properly use this
function?


Thank you
 
To dump the contents af a map (or any MFC collection) I usually just do it like this:

afxDump.SetDepth(1); // For dumping elements too
myCollection.Dump(afxDump);


/Per
Nerdy signatures are as lame as the inconsistent stardates of STTNG.
 
HI, I am maybe missing something here…
Here is an example of my problem

//MyClass1.h
#pragma once
#include <afxtempl.h>

class CMyClass1
{
public:
CMyClass1(void);
virtual ~CMyClass1(void);
protected:
CMap<int,int,CString,CString> m_myMap1;
};
//MyClass1.cpp
#include &quot;StdAfx.h&quot;
#include &quot;.\myclass.h&quot;

template <> void AFXAPI DumpElements<CString> (CDumpContext& dc, const
CString* pElements, INT_PTR nCount)
{
dc << *pElements;
}

template <> void AFXAPI DumpElements<int> (CDumpContext& dc, const
int* pElements, INT_PTR nCount)
{
dc << *pElements;
}

CMyClass1::CMyClass1(void)
{
for(int i=0; i<10; i++){
CString sStr;
sStr.Format(_T(&quot;String %d&quot;),i+1);
m_myMap1.SetAt(i,sStr);
}

afxDump.SetDepth(1);
m_myMap1.Dump(afxDump);
}
//MyClass2.h

#pragma once
#include <afxtempl.h>

class CMyClass2
{
public:
CMyClass2(void);
virtual ~CMyClass2(void);
protected:
CMap<int,int,CString,CString> m_myMap2;
};
If you include only the CMyClass1 into a project it will work fine, the DumpElements is working perfectly. But if you include CMyClass1 and CMyClass2 you will receive the following linker error.
myapp error LNK2005: &quot;void __stdcall DumpElements<int>(class CDumpContext &,int const *,int)&quot; (??$DumpElements@H@@YGXAAVCDumpContext@@PBHH@Z) already defined in MyClass1.obj
and one for the CString version of the DumpElements function.


Thank you

 
Well....
(assuming #include &quot;.\myclass.h&quot; should be &quot;MyClass1.h&quot;)

Is there DumpElements templates in MyClass2.cpp as well?

You could put them in an anonymnous namespace to separate unless you want to reuse them hade use the same for both classes.


/Per
Nerdy signatures are as lame as the inconsistent stardates of STTNG.
 
You are correct for the includes.

No in MYClass2 there is no definition of the DumpElements function. I tried to put the CMyClass1 into a namespace, it did not change anything.
 
Im a bit puzzled. There must be more to MyClass.* than described above...

/Per
Nerdy signatures are as lame as the inconsistent stardates of STTNG.
 
I mean MyClass2.*

/Per
Nerdy signatures are as lame as the inconsistent stardates of STTNG.
 
here is the complete listing of MyClass 1 & 2
Code:
//MyClass1.h
#pragma once
#include <afxtempl.h>

class CMyClass1
{
public:
  CMyClass1(void);
  virtual ~CMyClass1(void);
protected:
  CMap<int,int,CString,CString> m_myMap1;
};
//MyClass1.cpp
#include &quot;StdAfx.h&quot;
#include &quot;.\myclass1.h&quot;

template <> void AFXAPI DumpElements<CString> (CDumpContext& dc, const 
CString* pElements, INT_PTR nCount)
{
      dc << *pElements;
}

template <> void AFXAPI DumpElements<int> (CDumpContext& dc, const 
int* pElements, INT_PTR nCount)
{
      dc << *pElements;
}

CMyClass1::CMyClass1(void)
{
   for(int i=0; i<10; i++){
    CString sStr;
    sStr.Format(_T(&quot;String %d&quot;),i+1);
    m_myMap1.SetAt(i,sStr);
  }

  afxDump.SetDepth(1); 
  m_myMap1.Dump(afxDump);

}

CMyClass1::~CMyClass1(void)
{
}

//MyClass2.h
#pragma once
#include <afxtempl.h>

class CMyClass2
{
public:
  CMyClass2(void);
  virtual ~CMyClass2(void);
protected:

  //uncomment the next line to have the error
//CMap<int,int,CString,CString> m_myMap2;
};
//MyClass2.cpp
#include &quot;StdAfx.h&quot;
#include &quot;.\myclass2.h&quot;

CMyClass2::CMyClass2(void)
{
}

CMyClass2::~CMyClass2(void)
{
}
Is there a way to attach my zipped test project to this message?
 
Here is a reply I got from the microsoft.public.vc.mfc that seem to correct my problem.


Hello Sascha,

Sorry for the late response. Now I'd like to share the following
information with you:

I noticed that you implement DumpElements<CString> and DumpElements<int>
methods in MyClass1.cpp while MyClass2.cpp will use those in afxtempl.h,
that's the reason why the linker prompts LNK2005 for MyClass2.obj. To
resolve this problem, we should declare DumpElements methods of your own as
glable functions to override those in afxtempl.h. Please remove the
implementation of DumpElements methods from MyClass1.cpp, and add the
following code to stdafx.h and stdafx.cpp:

//-----------code snipeet---------------
//declare the methods in Stdafx.h
#include <afxtempl.h>
template <> void AFXAPI DumpElements<CString> (CDumpContext& dc, const
CString* pElements, INT_PTR nCount);
template <> void AFXAPI DumpElements<int> (CDumpContext& dc, const
int* pElements, INT_PTR nCount);

//Implement the functions in Stdafx.cpp
template <> void AFXAPI DumpElements<CString> (CDumpContext& dc, const
CString* pElements, INT_PTR
nCount)
{
dc << *pElements;
}

template <> void AFXAPI DumpElements<int> (CDumpContext& dc, const
int* pElements, INT_PTR nCount)
{
dc << *pElements;
}
//-------------end of--------------------------

Please feel free to let me know if you have any problems or concerns.

Have a nice day!

Regards,

HuangTM
Microsoft Online Partner Support
MCSE/MCSD
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top