【发布时间】:2012-07-18 02:52:24
【问题描述】:
我正在做我的第一份实习工作,仍在尝试在 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 结尾的函数调用,但只有一个似乎是在调用 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)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 article 听起来像是在代码正常工作并且编译器以某种方式设法丢失 .obj 文件或 .lib 文件时发生此错误。我怎样才能让它再次指向正确的地方?
呃, -亚历克斯
【问题讨论】:
-
你必须将这个怪物移植到Linux?节哀顺变。请注意,
LPCTSTR、DWORD等是类型定义,它们“衰减”(因为缺少正确的术语)到它们的实际 C 类型(这是相当糟糕的类型)。这些都是 Windows 主义,因此您最终需要为您的端口编写类似的 typedef 或全部替换它们。 -
这是一个链接器错误,而不是编译器错误。如果您遇到编译器错误,您用来尝试解决它的过程就是您要使用的过程。所有错误告诉你的是它找不到它需要链接的静态库,换句话说,它找不到包含函数 CWnd::create 的编译的文件。您必须转到 Visual Studio 中的链接器设置对话框并添加相关库。
-
CWnd 是 MFC 的一部分。确保您正在链接 MFC。更熟悉最近的 VS 的人可以告诉你如何做到这一点。
-
如何确定哪个文件包含CWnd::create的编译?我一直在寻找整个网络,并且知道它属于 Microsoft 基础类库,但似乎在该库中找不到实际 files 的提及。 MSDN 只是谈论类。此外,一旦我确定了需要将链接器指向的文件,我具体应该在哪里执行此操作?它会在项目属性->配置属性->图书馆员->通用->附加库目录下吗?
-
更新:我想那条路径毕竟行不通。请参阅下面我对 Scotty 回答的回复。要么它仍在尝试从其他一些设置链接,要么 mfc90.dll 不是我需要链接到的文件。有什么想法吗?
标签: c++ visual-studio-2008 linker-errors unresolved-external lnk2001