You may receive an LNK2019 error message when you build a Visual C++ 2005 or Visual C++ .NET application that uses a CString-derived class from a DLL file

Article translations Article translations
Article ID: 309801 - View products that this article applies to.
This article was previously published under Q309801
Note Microsoft Visual C++ 2005, Microsoft Visual C++ .NET 2003, and Microsoft Visual C++ .NET 2002 support both the managed code model that is provided by the Microsoft .NET Framework and the unmanaged native Microsoft Windows code model. The information in this article applies only to unmanaged Visual C++ code.
Expand all | Collapse all

On This Page

SYMPTOMS

When you build a Visual C++ 2005 or Visual C++ .NET application that uses a CString-derived class from a DLL file, you may receive an error message that is similar to one of the following:

Message 1
ClientProject error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall ATL::CStringT<char,class StrTraitMFC<char,class ATL::ChTraitsCRT<char>>>::CStringT<char,class StrTraitMFC<char,class ATL::ChTraitsCRT<char>>>(char const *)" (__imp_??0?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@QAE@PBD@Z) referenced in function _main
Message 2
ClientProject error LNK2005: "public: __thiscall ATL::CStringT<char,class StrTraitMFC<char,class ATL::ChTraitsCRT<char>>>::~CStringT<char,class StrTraitMFC<char,class ATL::ChTraitsCRT<char>>>(void)" (??1?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@QAE@XZ) already defined in Simple.obj
Message 3
ClientProject fatal error LNK1169: one or more multiply defined symbols found

CAUSE

This behavior may occur if you use a class derived from CString that is also exported from a DLL.

In Microsoft Visual Studio 2005 or in Microsoft Visual Studio .NET, the CString class has changed to a template class, as demonstrated by the following lines of code taken from afxstr.h:
typedef ATL::CStringT< wchar_t, StrTraitMFC< wchar_t > > CStringW;
typedef ATL::CStringT< char, StrTraitMFC< char > > CStringA;
typedef ATL::CStringT< TCHAR, StrTraitMFC< TCHAR > > CString;
				
Visual Studio automatically exports the appropriate template instantiation for the CStringT template class that you derive from. However, when you import the class, Visual Studio .NET sometimes does not correctly import that instantiation. This results in the linker error messages listed in the "Symptoms" section of this article.

RESOLUTION

To resolve this issue, explicitly import the template class for CStringT and CSimpleStringT in the precompiled header (stdafx.h) file, as follows:
template class __declspec(dllimport) CStringT<TCHAR, StrTraitMFC<TCHAR, ChTraitsCRT<TCHAR> > >;
template class __declspec(dllimport) CSimpleStringT<TCHAR>;
				

MORE INFORMATION

Steps to Reproduce the Problem

  1. In Visual C++ 2005 or in Visual C++ .NET, create a default MFC DLL project.
  2. On the Project menu, click Add New Item.
  3. Name the file MyString.h. Select the Header File template, and then click Open.

    Note In Visual Studio 2005, click Add instead of Open.
  4. Add the following code to MyString.h:
    #ifdef _USRDLL
    #define IMPEXP __declspec(dllexport)
    #else
    #define IMPEXP __declspec(dllimport)
    #endif 
    
    class IMPEXP CMyString: public CString
    {
       public:
          CMyString();
          virtual ~CMyString();
    
          void MyMethod();
    };
    					
  5. Add a new C++ source file to the project named MyString.cpp.
  6. Add the following code to MyString.cpp:
    #include "StdAfx.h"
    #include "mystring.h"
    
    CMyString::CMyString(void) {}
    CMyString::~CMyString(void) {}
    
    void CMyString::MyMethod(void)
    {
       AfxMessageBox( T ("foo is called") );
    
    }
    					
  7. Save and build the DLL project.
  8. Create a new Win32 Project. In the wizard, change the setting under Application Settings to the Console Application type, and then click to select the MFC checkbox to add MFC support.
  9. In the new application's main source file, include MyString.h from the DLL project. Verify that the correct full path or relative path is being used.
  10. Before the main function, add a #pragma to link to the library for the DLL (again, be sure to use a correct full path or relative path), as follows:
    #pragma comment(lib, "..\\Debug\\TestDll.lib")
    					
  11. Add the following code in the else block of the main function:
    // TODO: code your application's behavior here.
    CString strHello = T ("Hello") ;
    CMyString* myStr = new CMyString();
    myStr->MyMethod(); 
    					
  12. Build the project.

    The build fails with the "LNK2019" error.
  13. In the console application, add a new C++ source file named Simple.cpp.
  14. Add the following code to Simple.cpp:
    #include "stdafx.h"
    CString bar()
    {
       CString s =<?xm-insertion_mark_start author="v-bobbid" time="20080319T140037-0800"?> T (<?xm-insertion_mark_end?><?xm-deletion_mark author="v-bobbid" time="20080319T140041-0800" data=" "?>"Hi"<?xm-insertion_mark_start author="v-bobbid" time="20080319T140045-0800"?>)<?xm-insertion_mark_end?>;
       return s;
    }
    					
  15. Build the project again.

    You receive the "LNK2005" and "LNK1169" error messages.
  16. Apply the solution provided in the "Resolution" section of this article.

    The project should now build without errors.

Properties

Article ID: 309801 - Last Review: March 19, 2008 - Revision: 4.0
APPLIES TO
  • Microsoft Visual C++ 2005 Express Edition
  • Microsoft Visual C++ .NET 2003 Standard Edition
  • Microsoft Visual C++ .NET 2002 Standard Edition
Keywords: 
kbdll kberrmsg kbprb KB309801

Give Feedback

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com