From: Russ on 12 Nov 2009 17:46 Hi all. I must be doing something wrong but cannot figure it out. I have a data class and a list class, in an extension DLL, declared like this: >#define DllExport __declspec (dllexport) >class DllExport CRate : public CObject { >public: > DECLARE_SERIAL (CRate) > CRate () { m_Rate = 0; } > CRate (const CRate &in) { *this = in; } > > const CRate& operator= (const CRate& in) > { m_Rate = in.m_Rate; m_Date = in.m_Date; return *this; } > > bool operator== (const CRate& in); > bool operator!= (const CRate& in) { return ! (*this == in); } > > virtual void Serialize (CArchive& Ar); > > double m_Rate; > CString m_Date; >}; >class DllExport CRateList : public CList <CRate, CRate&> { >public: > DECLARE_SERIAL (CRateList) > > double GetRate () const { return GetHead ().m_Rate; } > double GetRate (const CString &da) const; > void SetRate (const double& d, const CString &da); > > const CRateList& operator= (const CRateList& in); > > bool operator== (const CRateList& in); > bool operator!= (const CRateList& in) > { return ! (*this == in); } >}; The implementation for serialization looks like this: >IMPLEMENT_SERIAL (CRate, CObject, 1) >IMPLEMENT_SERIAL (CRateList, CList, 1) If I leave DllExport out of the class declarations, everything compiles ok. It is still ok with DllExport only in the CRate class. But when I put DllExport in the CRateList class, I get a compile error like this: "error C2678: binary '==' : no operator found which takes a left-hand operand of type 'const CRate' (or there is no acceptable conversion)" This error is attributed to the last line of a helper function called CompareElements that looks like this (from afxtempl.h): >template<class TYPE, class ARG_TYPE> >BOOL AFXAPI CompareElements(const TYPE* pElement1, const ARG_TYPE* pElement2) >{ > ENSURE(pElement1 != NULL && pElement2 != NULL); > ASSERT(AfxIsValidAddress(pElement1, sizeof(TYPE), FALSE)); > ASSERT(AfxIsValidAddress(pElement2, sizeof(ARG_TYPE), FALSE)); > > return *pElement1 == *pElement2; >} As far as I can find, that helper is only called from CList::Find function, which I am not using... And anyway I cannot figure out why this only happens when I use dllexport. Help?? Thanks, Russ
From: Joseph M. Newcomer on 12 Nov 2009 23:34 See below... On Thu, 12 Nov 2009 17:46:46 -0500, Russ <russk2t(a)comcast.net> wrote: >Hi all. I must be doing something wrong but cannot figure it out. I >have a data class and a list class, in an extension DLL, declared like >this: > >>#define DllExport __declspec (dllexport) > >>class DllExport CRate : public CObject { >>public: >> DECLARE_SERIAL (CRate) >> CRate () { m_Rate = 0; } >> CRate (const CRate &in) { *this = in; } >> >> const CRate& operator= (const CRate& in) >> { m_Rate = in.m_Rate; m_Date = in.m_Date; return *this; } >> >> bool operator== (const CRate& in); **** bool operator==(const CRate & in) const; **** >> bool operator!= (const CRate& in) { return ! (*this == in); } **** bool operator != (const CRate & in) const {return !(*this == in); } **** >> >> virtual void Serialize (CArchive& Ar); >> >> double m_Rate; >> CString m_Date; >>}; > > >>class DllExport CRateList : public CList <CRate, CRate&> { >>public: >> DECLARE_SERIAL (CRateList) >> >> double GetRate () const { return GetHead ().m_Rate; } >> double GetRate (const CString &da) const; >> void SetRate (const double& d, const CString &da); >> >> const CRateList& operator= (const CRateList& in); >> >> bool operator== (const CRateList& in); >> bool operator!= (const CRateList& in) >> { return ! (*this == in); } >>}; > >The implementation for serialization looks like this: > >>IMPLEMENT_SERIAL (CRate, CObject, 1) >>IMPLEMENT_SERIAL (CRateList, CList, 1) > > >If I leave DllExport out of the class declarations, everything >compiles ok. It is still ok with DllExport only in the CRate class. >But when I put DllExport in the CRateList class, I get a compile error >like this: > > "error C2678: binary '==' : no operator found which takes a left-hand >operand of type 'const CRate' (or there is no acceptable conversion)" > >This error is attributed to the last line of a helper function called >CompareElements that looks like this (from afxtempl.h): > >>template<class TYPE, class ARG_TYPE> >>BOOL AFXAPI CompareElements(const TYPE* pElement1, const ARG_TYPE* pElement2) >>{ >> ENSURE(pElement1 != NULL && pElement2 != NULL); >> ASSERT(AfxIsValidAddress(pElement1, sizeof(TYPE), FALSE)); >> ASSERT(AfxIsValidAddress(pElement2, sizeof(ARG_TYPE), FALSE)); >> >> return *pElement1 == *pElement2; >>} > > >As far as I can find, that helper is only called from CList::Find >function, which I am not using... And anyway I cannot figure out why >this only happens when I use dllexport. > >Help?? > >Thanks, Russ Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Goran on 13 Nov 2009 02:40 On Nov 12, 11:46 pm, Russ <russ...(a)comcast.net> wrote: > As far as I can find, that helper is only called from CList::Find > function, which I am not using... And anyway I cannot figure out why > this only happens when I use dllexport. You need bool op==(...) __const__; // __ emphasis mine. This is, I guess, because you are exporting a class that derives from the template class. Since compiler does not know class will be used by client code (it can't, that code is in another module), compiler forces the generation of all members for given base class. Some of these members use CompareElements. But your op== is not correct (and, you see, CompareElements takes const TYPE* and then calls op==). I wouldn't export like that. In CRateList, I would expose an interface I think should be exposed (even if it is a bastardized CList part). I would either contain CList in CRateList or perhaps derive privately. What I am saying, BTW, stems from the general rule of thumb "prefer containment to inheritance". goran.
From: Russ on 13 Nov 2009 12:25 Thanks Joe (and Goran) for the help. I must have looked at those declarations 50 times - and still did not see that I had somehow dropped the const from the operator== and operator!= functions. Of course it works now. Thanks again, Russ On Thu, 12 Nov 2009 23:34:28 -0500, Joseph M. Newcomer <newcomer(a)flounder.com> wrote: >See below... >On Thu, 12 Nov 2009 17:46:46 -0500, Russ <russk2t(a)comcast.net> wrote: > >>Hi all. I must be doing something wrong but cannot figure it out. I >>have a data class and a list class, in an extension DLL, declared like >>this: >> >>>#define DllExport __declspec (dllexport) >> >>>class DllExport CRate : public CObject { >>>public: >>> DECLARE_SERIAL (CRate) >>> CRate () { m_Rate = 0; } >>> CRate (const CRate &in) { *this = in; } >>> >>> const CRate& operator= (const CRate& in) >>> { m_Rate = in.m_Rate; m_Date = in.m_Date; return *this; } >>> >>> bool operator== (const CRate& in); >**** > bool operator==(const CRate & in) const; >**** >>> bool operator!= (const CRate& in) { return ! (*this == in); } >**** > bool operator != (const CRate & in) const {return !(*this == in); } >**** >>> >>> virtual void Serialize (CArchive& Ar); >>> >>> double m_Rate; >>> CString m_Date; >>>}; >> >> >>>class DllExport CRateList : public CList <CRate, CRate&> { >>>public: >>> DECLARE_SERIAL (CRateList) >>> >>> double GetRate () const { return GetHead ().m_Rate; } >>> double GetRate (const CString &da) const; >>> void SetRate (const double& d, const CString &da); >>> >>> const CRateList& operator= (const CRateList& in); >>> >>> bool operator== (const CRateList& in); >>> bool operator!= (const CRateList& in) >>> { return ! (*this == in); } >>>}; >> >>The implementation for serialization looks like this: >> >>>IMPLEMENT_SERIAL (CRate, CObject, 1) >>>IMPLEMENT_SERIAL (CRateList, CList, 1) >> >> >>If I leave DllExport out of the class declarations, everything >>compiles ok. It is still ok with DllExport only in the CRate class. >>But when I put DllExport in the CRateList class, I get a compile error >>like this: >> >> "error C2678: binary '==' : no operator found which takes a left-hand >>operand of type 'const CRate' (or there is no acceptable conversion)" >> >>This error is attributed to the last line of a helper function called >>CompareElements that looks like this (from afxtempl.h): >> >>>template<class TYPE, class ARG_TYPE> >>>BOOL AFXAPI CompareElements(const TYPE* pElement1, const ARG_TYPE* pElement2) >>>{ >>> ENSURE(pElement1 != NULL && pElement2 != NULL); >>> ASSERT(AfxIsValidAddress(pElement1, sizeof(TYPE), FALSE)); >>> ASSERT(AfxIsValidAddress(pElement2, sizeof(ARG_TYPE), FALSE)); >>> >>> return *pElement1 == *pElement2; >>>} >> >> >>As far as I can find, that helper is only called from CList::Find >>function, which I am not using... And anyway I cannot figure out why >>this only happens when I use dllexport. >> >>Help?? >> >>Thanks, Russ >Joseph M. Newcomer [MVP] >email: newcomer(a)flounder.com >Web: http://www.flounder.com >MVP Tips: http://www.flounder.com/mvp_tips.htm
|
Pages: 1 Prev: Migrating VC6.0 -> Visual Studion 2008 - depricated functions Next: MASM documentation |