提问人:Alex Jansen 提问时间:7/19/2012 最后编辑:CommunityAlex Jansen 更新时间:7/19/2012 访问量:1296
如何跟踪此链接器错误?
How do I follow this linker error?
问:
我正在做我的第一个实习,仍然试图在Visual Studio 2008上编译这个可怕的东西。我花了一周的时间研究 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 结尾的函数调用,但只有一个似乎在调用 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。那里什么都没有,所以我在 IDE 设置中查看了 VC++ 目录包含。第一个列表是:$(WindowsSdkDir)\include,所以我查找了 WindowsSdkDir 环境变量,当然它不存在。我也检查了注册表。没有骰子。最终,我发现可以通过单击项目配置窗口中文本字段最右端出现的省略号 (...) 之一并展开“宏”窗格来解析这些符号名称。通过这样做,我发现$(WindowsSdkDir)指向:C:\Program Files\Microsoft SDKs\Windows\v6.0A\,所以我去了那里,打开了Include文件夹,没有找到afxwin.h文件。$(FrameworkSDKDir)include 指向与 $(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 文章听起来像是当代码工作正常并且编译器以某种方式设法丢失 .obj 文件或 .lib 文件时会发生此错误。我怎样才能让它再次指向正确的位置?
呸 -亚历克斯
答:
链接器错误意味着它找到了标头,但找不到实现(obj 或 lib)。检查标头是否存在是没有意义的 - 您的代码已编译,因此编译器找到了标头。
看起来您需要链接到 MFC(即包含 CWnd 实现的库)。
在项目属性中,设置:
General > Use of MFC > Use MFC in a Shared DLL
至于 stdafx.h,它是一个预编译的头文件。您可以自己阅读这些内容。;)如果不需要它,可以在项目属性中将其关闭:
C/C++ > Precompiled Headers > Precompiled Header > Not Using Precompiled Headers
评论
LPCTSTR
DWORD