Microsoft Study Bible

December 2, 2009

Error LNK2001 (C++)

Filed under: Server technologies — Tags: , , , , — Jackson @ 4:58 am

Would you have such an experience: you try to build program in C++ code. All of the code is simple and legal, however, when you compile link with your programs, the following link errors happen:

>error LNK2001: unresolved external symbol _purecall

To resolve this problem or know better how we make this mistake, firstly we will reproduce this error together. Create a new win32 project, and open the project settings in VS, and modify the projects bellow:

1.     set “ enable C++ exception “ as” false”

2.     set “Basic Runtime Checks” as “default”

3.     set “Buffer security check” as “false (/GS-)”

4.     set “Enable Run-Time Type Information” as “false (/GR-)”

5.     set “Ignore all default libraries ” as “yes (/NODEFAULTLIB)”

Then, you will input the following code in the source file:

C++ code:

1.       #include <Windows.h>   

2.       #include <tchar.h>   

3.         

4.       voidoperator new(size_t _Size)   

5.       {   

6.           return HeapAlloc(GetProcessHeap(), 0, _Size);   

7.       }   

8.         

9.       void operator delete(void* ptr)   

10.   {   

11.       HeapFree(GetProcessHeap(), 0, ptr);   

12.   }   

13.     

14.   class A   

15.   {   

16.   public:   

17.       virtual void foo(void) = 0;   

18.   };   

19.     

20.   class B : public A   

21.   {   

22.   public:   

23.       void foo(void)   

24.       {   

25.           OutputDebugString(_T(“Hello, World!”));   

26.       }   

27.   };   

28.     

29.   extern “C” void WinMainCRTStartup(void)   

30.   {   

31.       A* p = new B;   

32.       p->foo();   

33.       delete p;   

34.   }  

Let me explain error.when we modify the Project Settings, in fact, that strip the project of the dependence to CRT .So, all of the codes are must be achieved by itself ,including new, delete and the program entry—winMainCRTStartup.After the code are input ,when we build the project ,we will get that link error.

Although  the project are not built successfully, we still use the Disassembly tool to open the obj file produced by the code complier,where we can find all of the secrets .Then I will introduce simply the construction process of the object B, and won’t list the assembly code.

1.     call new to apply memory space

2.     call A::A,use the virtual table in A class to initialize the subobject of A class.

3.     call B::B, use the virtual table in B class to initialize the object.

The problem appears in the step 2: A class is a pure virtual class .So what is its virtual table? I find the table in the obj file, as followings.

public ??_7A@@6B@
; const A::`vftable’
??_7A@@6B@      dd offset __purecall

As you can see, although A::foo is a pure virtual function, the compiler gave it a field in the virtual table, whose content just was replaced of the symbol named _purecall. Since the symbol _purecall exists in the default CRT, while we have stripped of the dependence to CRT, the error LNK 2001 appeared when we compiled link.

It is not hard to resolve the problem, in my opinion. You just prepare another simple _purecall.

View plaincopy to clipboardprint?

1.        extern ”C” int __cdecl _purecall(void)   

2.        {   

3.            return 0;   

4.        }  

Besides, the C++ compiler in VS provides the special support in such cases. We can use _declspec(novtable) to define the pure virtual class of the novtable.So ,you can consider the following code to resolve the problem ,too .

view plaincopy to clipboardprint?

1.        class __declspec(novtable) A   

2.        {   

3.        public:   

4.            virtual void foo(void) = 0;   

};

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress

Close
E-mail It