Re: Exporting CString from a DLL
On Thu, 28 Feb 2008 11:38:07 -0500, "EricW" <empty@empty.com> wrote:
Hi All,
I'm trying to use a CString variable in a class that is exported from a
DLL and I'm getting the linker errors below. I changed the CString
declaration to CStringEx and exported that class like below which resulted
in the errors. If I take the regrettable step of commenting out the
declaration of CString, CStringA and CStringW in altstr.h (I'm not using MFC
at all) and replacing it with the corresponding CStringExA/W it seems
better, but that is solution I'd rather not do. Is there any other way to
use CString in a DLL.
Thanks,
EricW
class __declspec( dllexport ) Test
{
public:
CStringWEx m_strName;
};
CStringWEx is a class I derived from the base CString classes.
ServerEngine.lib(ServerEngine.dll) : error LNK2005: "public: __thiscall
ATL::CStringT<wchar_t,class ATL::StrTraitATL<wchar_t,class
ATL::ChTraitsCRT<wchar_t> > >::~CStringT<wchar_t,class
ATL::StrTraitATL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >(void)"
(??1?$CStringT@_WV?$StrTraitATL@_WV?$ChTraitsCRT@_W@ATL@@@ATL@@@ATL@@QAE@XZ)
already defined in AdminMsgs.obj
ServerEngine.lib(ServerEngine.dll) : error LNK2005: "public: __thiscall
ATL::CSimpleStringT<wchar_t,0>::operator wchar_t const *(void)const "
(??B?$CSimpleStringT@_W$0A@@ATL@@QBEPB_WXZ) already defined in AdminMsgs.obj
ServerEngine.lib(ServerEngine.dll) : error LNK2005: "public: class
ATL::CStringT<wchar_t,class ATL::StrTraitATL<wchar_t,class
ATL::ChTraitsCRT<wchar_t> > > & __thiscall ATL::CStringT<wchar_t,class
ATL::StrTraitATL<wchar_t,class ATL::ChTraitsCRT<wchar_t> >
::operator=(class ATL::CStringT<wchar_t,class
ATL::StrTraitATL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > > const &)"
(??4?$CStringT@_WV?$StrTraitATL@_WV?$ChTraitsCRT@_W@ATL@@@ATL@@@ATL@@QAEAAV01@ABV01@@Z)
already defined in ErrorLogOptionsDlg.obj
ServerEngine.lib(ServerEngine.dll) : error LNK2005: "public: __thiscall
ATL::CStringT<wchar_t,class ATL::StrTraitATL<wchar_t,class
ATL::ChTraitsCRT<wchar_t> > >::CStringT<wchar_t,class
ATL::StrTraitATL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >(void)"
(??0?$CStringT@_WV?$StrTraitATL@_WV?$ChTraitsCRT@_W@ATL@@@ATL@@@ATL@@QAE@XZ)
already defined in AdminMsgs.obj
http://msdn2.microsoft.com/en-us/library/ms174286(VS.80).aspx
To begin, use the following exporting technique. Replace your direct use of
the __declspec with X_EXPORT, replacing "X" with the name of your DLL,
making sure it has a reasonable chance of being unique:
#ifdef COMPILING_X_DLL
#define X_EXPORT __declspec(dllexport)
#else
#define X_EXPORT __declspec(dllimport)
#endif
Then #define COMPILING_X_DLL only in that DLL's project. This method can be
used by multiple DLLs, and since the macro names are unique, they don't
conflict.
Also, CString has no virtual functions and thus is not a good candidate for
public derivation. Consider using plain old CString and extending its
interface through non-member functions.
Finally, if you want to stick with CStringWEx, try to reproduce the problem
in a minimal DLL consisting of two files, a.cpp and b.cpp, which you can
compile at the command line with:
cl -LD -MD -D_AFXDLL a.cpp b.cpp
If you don't discover the solution along the way, post the files here,
including the definition of CStringWEx.
--
Doug Harrison
Visual C++ MVP