如何遵循此链接器错误?

时间:2012-07-18 23:54:45

标签: c++ visual-studio-2008 linker-errors unresolved-external lnk2001

我正在进行第一次实习,仍然在Visual Studio 2008上尝试get this horrible thing to compile。我花了一周时间玩IDE设置和Windows SDK安装,我不认为我会去在这个方向上取得更多进展。每个人都在这里度假,我没有高级工程师可以求助。帮我Stack Overflow,你是我唯一的希望!

今天,我正在尝试跟踪具体的错误,所以我有一些想法为什么一切都在破坏。也许那时我会更好地了解如何解决它。在过去的几个小时里,我一直在研究这个:

6>ResizableLib.lib(ResizablePage.obj) : error LNK2001: unresolved external symbol "public: virtual int __thiscall CWnd::Create(char const *,char const *,unsigned long,struct tagRECT const &,class CWnd *,unsigned int,struct CCreateContext *)" (?Create@CWnd@@UAEHPBD0KABUtagRECT@@PAV1@IPAUCCreateContext@@@Z)

我的理解是无法从我正在使用的ResizableLib项目中找到CWnd :: Create函数。我想我会找到它被调用的文件,并跟踪包含以查看它是否应该在调用它时具有CWnd :: Create的定义。我开始通过搜索整个项目(alt + E + F + I)来创建(因为我认为这将获得调用Create函数的每个实例。我发现其他几个函数以Create结束,但只有一个似乎是在调用Create函数本身:

ResizableGrip.cpp(127): BOOL bRet = m_wndGrip.Create(WS_CHILD | WS_CLIPSIBLINGS

所以......我打开了ResizableGrip.cpp并查看了包含。该文件的第一行是:

#include "stdafx.h"

我想我会查看该文件,看看是否有CWnd :: Create的函数声明,或者某种继承版本。包含此文件没有预处理器条件(因为此程序中有许多其他点),所以我认为可以安全地说将包含stdafx.h。为了找出将包含哪个 stdafx.h文件(通常用于stdafx.h文件的是什么?我看到它们到处都是!),我首先看了同一个目录作为ResizableGrip.cpp文件,因为我相信在检查项目中的附加包含路径之前,编译器首先查找与包含文件相同的目录,最后是Visual Studio VC ++主要设置中列出的包含路径。它是否正确?无论如何,StdAfx.h文件位于同一目录中,因此我得出结论,这将是包含的文件。该文件的前几行看起来像这样:

#if !defined(AFX_STDAFX_H__0A781DD9_5C37_49E2_A4F5_E517F5B8A621__INCLUDED_)
#define AFX_STDAFX_H__0A781DD9_5C37_49E2_A4F5_E517F5B8A621__INCLUDED_
#pragma message("StdAfx CommonClasses/ResizableLib")
#ifdef INC_DEBUG
#pragma message("In ResizeLib::StdAfx.h") 
#endif

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#if _MSC_VER >= 1300
#define  WINVER      0x0500
#define _WIN32_WINNT 0x0500
#endif

#define VC_EXTRALEAN        // Exclude rarely-used stuff from Windows headers

#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>         // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT

我承认我并不完全理解这里发生的所有预处理器事情,但由于#include没有条件限制,我认为它也包含在内。项目目录中没有afxwin.h文件,因此我查看了项目的其他包含。唯一指定的地方是.... \ COMMON,所以我去了两个目录,找到了COMMON文件夹,并查找了afxwin.h。那里什么都没有,所以我查看了VC ++目录包含的IDE设置。第一个列表是:$(WindowsSdkDir)\ include所以我查找了WindowsSdkDir环境变量,当然这个变量不存在。我也检查了注册表。没有骰子。最后,我发现您可以通过单击项目配置窗口中文本字段最右端出现的其中一个省略号(...)来解析这些符号名称,当您单击它们并展开宏时窗格。通过这样做,我发现$(WindowsSdkDir)指向:C:\ Program Files \ Microsoft SDKs \ Windows \ v6.0A \所以我去了那里,打开了Include文件夹,发现没有afxwin.h文件。 $(FrameworkSDKDir)包括指向与$(WindowsSdkDir)\ include相同的位置,所以我继续到Visual Studio VC ++目录包含列表中的下一行:$(VCInstallDir)atlmfc \ include哪个解析为C:\ Program Files \ Microsoft Visual Studio 9.0 \ VC \ atlmfc \ include \我终于找到了afxwin.h。在这个文件中最后有一个名为Cwnd的类,其中一个名为Create的函数定义如下:

virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);

我不知道这些参数是什么,但我假设这是链接器最初抱怨的函数的一个极度重新定义的版本:

CWnd::Create(char const *,char const *,unsigned long,struct tagRECT const &,class CWnd *,unsigned int,struct CCreateContext *)

否则,在链接器接管之前,编​​译器不会将其作为函数的不同版本捕获吗?实际上,现在我考虑了它(因此我发布的全部原因),我想我所做的就是像解决编译器错误一样遍历代码。我甚至做到了吗?这件事是一个怪物,我只是在这里猜测。

再次,就像标题所说的那样,你应该如何跟踪链接器错误?是否有类似于我在这里所做的过程? MSDN article使得听起来好像这个错误在代码工作正常并且编译器以某种方式设法丢失.obj文件或.lib文件时发生。我怎样才能让它再次指向正确的位置?

哎, -Alex

1 个答案:

答案 0 :(得分:0)

链接器错误意味着找到了头但找不到实现(obj或lib)。没有必要检查标头是否存在 - 您的代码已编译,因此编译器找到了标头。

看起来您需要链接到MFC (即包含CWnd实现的lib)。

在项目属性中,设置:

General > Use of MFC > Use MFC in a Shared DLL

对于stdafx.h,它是预编译头。你可以自己阅读这些内容。 ;)如果您不想要它,可以在项目属性中将其关闭:

C/C++ > Precompiled Headers > Precompiled Header > Not Using Precompiled Headers