Article ID: 152254 - Last Review: November 21, 2006 - Revision: 4.1

BUG: You receive an error LNK2001 when you try to use the >> operator to serialize one of the extension DLL classes in Visual C++

This article was previously published under Q152254

On This Page

Expand all | Collapse all

SYMPTOMS

When attempting to build an application that uses classes from an MFC extension DLL, the linker reports an error of the form:
   mainfrm.obj : error LNK2001: unresolved external symbol
       "class CArchive & __stdcall operator>>
           (class CArchive &,class CClassInExtDLL * &)"
               (??5@YGAAVCArchive@@AAV0@AAPAVCDummyDoc@@@Z)
					
Specifically, this problem occurs for code that attempts to use the >> operator to serialize one of the extension DLL classes that use the DECLARE_SERIAL macro.

CAUSE

If an exported class is declared in an extension DLL and is made serializable by the use of the macros DECLARE_SERIAL and IMPLEMENT_SERIAL, the global function:
   friend CArchive& AFXAPI operator>>(CArchive& ar, CMyObject* &pOb);
				
is not automatically exported along with the class. Therefore, if an application tries to serialize an object of that class type by the use of the >> operator, a LNK2001 unresolved external error occurs on operator >>.

RESOLUTION

Create a new macro based on the DECLARE_SERIAL macro:
   #define DECLARE_SERIAL_EXTDLL(class_name)   \ 
           _DECLARE_DYNCREATE(class_name)      \ 
           AFX_EXT_API friend CArchive& AFXAPI \ 
           operator>>(CArchive& ar, class_name* &pOb);
				
After defining this macro, use this new DECLARE_SERIAL_EXTDLL macro in place of DECLARE_SERIAL in the class declaration. Rebuild the DLL and link its new import library with the application.

In this resolution, the AFX_EXT_API prefix resolves the LNK2001 error by explicitly exporting the function operator>> when building the extension DLL.

STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article.

MORE INFORMATION

In order to make a class serializable by the use of a CArchive object, the class must be derived from CObject and must implement the DECLARE_SERIAL and IMPLEMENT_SERIAL macros. These macros are needed because they define an overloaded function, operator>>, explicitly for that class. In a case where that class is defined in an extension DLL and is exported by using the AFX_EXT_CLASS macro, the overloaded function, operator>>, does not get exported along with the class. Thus, if the main application instantiates an object of that class type and tries to serialize that object by the use of a CArchive object, a LNK2001 unresolved external error will occur.

Sample Code

Declare your class in the extension DLL this way:

In the header (.h) file for CMyObject:
   #define DECLARE_SERIAL_EXTDLL(class_name)   \ 
           _DECLARE_DYNCREATE(class_name)      \ 
           AFX_EXT_API friend CArchive& AFXAPI \ 
           operator>>(CArchive& ar, class_name* &pOb);

   class AFX_EXT_CLASS CMyObject : public CObject
   {
       DECLARE_SERIAL_EXTDLL(CMyObject)
       ...

   };

   In the implementation (.cpp) file for CMyObject:

   ...

   IMPLEMENT_SERIAL(CMyObject, CObject, YOUR_SCHEMA_NUMBER_HERE)

   ...
				

REFERENCES

For additional information on serialization and how to export classes from extension DLL's, please see:

  • MFC TechNote #2 in the Books Online
  • MFC TechNote #33 in the Books Online
For more information, click the following article number to view the article in the Microsoft Knowledge Base:
131946  (http://support.microsoft.com/kb/131946/ ) Bad pointer from RUNTIME_CLASS with class from _AFXDLL

APPLIES TO
  • Microsoft Foundation Class Library 4.2, when used with:
    • Microsoft Visual C++ 4.0 Standard Edition
    • Microsoft Visual C++ 4.1 Subscription
    • Microsoft Visual C++ 4.2 Enterprise Edition
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Enterprise Edition
    • Microsoft Visual C++ 4.2 Professional Edition
    • Microsoft Visual C++ 5.0 Professional Edition
    • Microsoft Visual C++ 6.0 Professional Edition
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
    • Microsoft Visual C++ .NET 2003 Standard Edition
    • Microsoft Visual C++ .NET 2002 Standard Edition
Keywords: 
kberrmsg kbtshoot kbbug kbdll kbprogramming KB152254
 

Article Translations