You receive a LNK2001 error when you link Visual C++ 5.0 and Visual C++ 6.0 binaries (248883)



The information in this article applies to:

  • Microsoft Visual C++, 32-bit Editions 6.0
  • Microsoft Visual C++, 32-bit Editions 5.0
  • Microsoft Visual C++ .NET (2002)
  • Microsoft Visual C++ .NET (2003)
  • Microsoft Visual C++ 2005 Express Edition

This article was previously published under Q248883
Note Microsoft Visual C++ .NET 2002 and Microsoft Visual C++ .NET 2003 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. Microsoft Visual C++ 2005 supports both the managed code model that is provided by the Microsoft .NET Framework and the unmanaged native Microsoft Windows code model.

SUMMARY

When you try to build an executable (.exe) file in Visual C++ 6.0 that references a constant array variable that is defined in a Visual C++ 5.0 dynamic link library (DLL) or a Visual C++ 5.0 static library, you receive the following link error:
error LNK2001: unresolved external symbol
This also occurs under the following circumstances:
  • You try to build an .exe file in Visual C++ 5.0 with a Visual C++ 6.0 DLL or a Visual C++ 6.0 static library.
  • You try to build an .exe file in Visual C++ .NET with a Visual C++ 5.0 DLL or a Visual C++ 5.0 static library.
  • You try to build an .exe file in Visual C++ 5.0 with a Visual C++ .NET DLL.

CAUSE

The Visual C++ 5.0 and Visual C++ 6.0 compilers generate decorated names for a constant array symbol differently. This is because the compilers treat the constant qualifier in the declaration of the array variable differently. For example, in the following code:
extern const long test[2] = { 1,2 };
the array variable that is named test in Visual C++ 5.0 is a pointer to a constant array. However, in Visual C++ 6.0, the same array variable is a constant pointer to a constant array.

WORKAROUND

When you generate a Visual C++ 5.0 DLL or static library that exports a constant array variable (to be referenced by a Visual C++ 6.0 .exe file), you can add the following EXPORTS entry to the module definition (DEF) file to generate the DLL or static library. This DEF file maps the internal symbol "?test@@3PBJB" to an external symbol '"?test@@3QBJB" as follows:
EXPORTS
	?test@@3QBJB=?test@@3PBJB
Similarly, when you export a constant array variable from a Visual C++ 6.0 DLL or Visual C++ 6.0 static library (to be referenced in a Visual C++ 5.0 .exe file), you can add the following EXPORTS entry to the DEF file to generate the DLL or static library:
EXPORTS
	?test@@3PBJB=?test@@3QBJB
To use the DEF file to generate the DLL, follow these steps:

Note Assume that the module definitions are stored in a file that is named library.def.
  1. Assume that the code for the DLL is library.cpp. At the command prompt type the following command to create an object library:
    cl /c library.cpp
  2. At the command prompt type the following command to create a dynamic link library:
    link /dll /def:library.def library.obj

    where library.obj is the object file that is generated in Step 1.

STATUS

This behavior is by design.

MORE INFORMATION

Steps to Reproduce the Behavior


  1. Open Notepad. On the File menu, click New.
  2. Paste the following code:
    __declspec(dllexport) extern const long test[2] = { 1,2 };
  3. Click Save. In the Save dialog box, type library.cpp as the name of the file
  4. To create a DLL, follow these steps:
    1. At the command prompt type the following command to create an object file from the .cpp file:
      cl /c library.cpp
      The object file that is created is library.obj.
    2. At the command prompt, type the following command to create a DLL from the object file that is created in Step a:
      link /dll library.obj
  5. At the command prompt, type the following command:
    dumpbin /exports library.dll
    where library.dll is the DLL that is generated in Step b.

    In the output of the dumpbin command notice the "?test@@3PBJB" decorated name that is generated for the constant array by the compiler.
  6. Follow the steps in the "Workaround" section of this article to create a DLL in Visual C++ 6.0. The decorated name that is generated for the constant array variable that is named test is '"test@@3QBJB".

The LNK2001 error that is described in the Symptoms section occurs because the compilers for the constant array variable for Visual C++ 6.0, and for Visual C++ 5.0 generate different decorated names. The error occurs when you try to link the following
  • A constant array reference in a Visual C++ 6.0 .exe, to a constant array definition in a Visual C++ 5.0 DLL or Visual C++ 5.0 static library
  • A constant array reference in a Visual C++ 5.0 .exe to the constant array definition in a Visual C++ 6.0 DLL or Visual C++ 6.0 static library
  • A constant array reference in a Visual C++ .NET .exe to a constant array definition in a Visual C++ 5.0 DLL or Visual C++ 5.0 static library. (Decorated names that are generated by the Visual C++ .NET compiler for constant array variables are the same as those of the Visual C++ 6.0 compiler.)

REFERENCES

For additional information about the LNK2001 linker error , click the following article number to view the article in the Microsoft Knowledge Base:

138400 Troubleshooting LNK2001 or L2029 Unresolved External Errors


For additional information about the DUMPBIN build tool, see the "DUMPBIN Reference" topic in the Visual C++ Concepts documentation on the following Microsoft Developer Network (MSDN) Web site
DUMPBIN Reference
For additional information about Module-Definition (DEF) files, see the eMbedded Visual C++ Guide on the following MSDN) Web site:
Module-Definition (.DEF) Files
For additional information about decorated names, see the following MSDN Web site:
Decorated Names

Modification Type:MajorLast Reviewed:1/9/2006
Keywords:kbtshoot kbnofix kbprb kbCompiler KB248883 kbAudDeveloper kbAudITPRO