未解决的外部梦魇

时间:2012-07-13 21:56:35

标签: c++ mfc doxygen lnk2019 lnk2001

Hello行业资深人士,

我是大学三年级学生,开始了我的第一个夏季编程实习,而且我在我的脑海中。我所工作的公司从另一家公司购买了一个巨大的应用程序,自90年代初以来,该公司已经慢慢扩展和修改它。该解决方案包含超过200,000行代码,分布在300多个文件中。据称整个解决方案都是按照ANSI-C ++标准编写的。代码几乎完全没有记录,大部分代码对我来说都是象形文字。最终,我的工作是将此代码移植到嵌入式Linux。目前,我的工作只是在Windows XP上使用Visual Studio 2008进行编译。

今天,我遇到了链接器错误,例如:

libcmtd.lib(sprintf.obj) : error LNK2005: _sprintf already defined in msvcrtd.lib(MSVCR90D.dll)

我的理解是,当使用不同的runtime libraries编译解决方案中的不同项目时,通常会发生这种情况。我的解决方案中有6个项目。其中4个设置为使用多线程调试DLL运行时库(/ MDd)进行编译,其中一个设置为使用多线程调试库(/ MTd)进行编译,其中一个设置为使用多线程DLL运行时库(/ MD)。我收到此错误消息后尝试的第一件事是将/ MTd和/ MD开关更改为/ MDd,以便所有内容都使用相同的运行时库进行编译。不幸的是,这导致了afx.h中的以下错误:

fatal error C1189: #error : Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d]

经过一番挖掘,我发现它已经告诉我我需要做什么了。我继续将Project Properties-> Configuration Properties-> General下的“使用MFC”选项更改为“在共享DLL中使用MFC”。此时我开始收到许多未解决的外部错误,例如:

dataPropertySheet.obj : error LNK2019: unresolved external symbol "public: __thiscall CResizableSheet::CResizableSheet(unsigned short const *,class CWnd *,unsigned int)" (??0CResizableSheet@@QAE@PBGPAVCWnd@@I@Z) referenced in function "public: __thiscall CdataPropertySheet::CdataPropertySheet(unsigned short const *,class CWnd *,unsigned int)" (??0CdataPropertySheet@@QAE@PBGPAVCWnd@@I@Z)

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)

在阅读LNK2001LNK2019上的MSDN页面后,我意识到我不知道发生了什么。这些不是他们告诉我们如何在学校处理的问题。我知道我的数据结构,这就是它。我最终走到现在的位置超出了我的范围!

从我有限的知识来看,似乎这些模块的各种调试版本都在预处理器指令和#include网络中纠缠不清。在环境变量,文件名,宏等可能的解决方案中,几乎每个头文件和源文件都有许多嵌套的#ifdef检查和#define语句。通过对我的编译器设置进行微小的更改,我似乎将程序的大部分内容重定向到具有非常不同的函数定义的不同库。这是我对正在发生的事情的模糊概念理解。

在我有机会排除这些编译错误之前,我觉得我需要更好地理解这段代码是如何工作的。为此,我一直试图逐行浏览许多文件,以查看它们的引导位置,范围内的对象和变量,等等。不幸的是,这并没有让我走得太远,因为对外部函数的每次调用都是模糊的,我无法通过预处理程序看到任何给定函数应该被调用的版本。

我正在寻找魔术解决方案来制定程序并尝试理解它。我尝试了一个叫Doxygen的,但要么我不知道如何正确使用它,要么就像我一样对预处理器的东西感到困惑。

我的问题是:
我剩下的选项是什么?

此时它之间有一个折腾:
a。)切换专业士 b。)跳下桥梁

这些选择都不会帮助我更好地理解这个代码库并进行编译。有没有人有更好的想法?类似的经历?贤者智慧分享?

非常感谢, -Alex

3 个答案:

答案 0 :(得分:3)

您似乎正在使用CodeProject中的CResizableSheet和CResizeablePage。如果您正在使用该页面中编译的静态库,您可以尝试下载源代码并使用匹配的/ MDd设置进行编译,并使用项目的链接器输入部分中的.lib输出。我还建议做一个干净的全部(转到build->批量构建 - >选择所有然后单击清除),然后再次尝试构建以确保一切都是最新的。

答案 1 :(得分:2)

我听说护理是一个很棒的课程......

冒着迂腐的风险,你所面临的是链接器错误,而不是编译器错误。我的基本方法是创建一个新的解决方案,并开始一次添加一个项目,让每个项目轮流构建。

我也会认真考虑尽可能地标准化每个项目的设置。最简单的方法是在新解决方案中创建空项目,并将现有代码复制到其中。

首先,您应该采取以下设置(与MFC相关):

调试:在共享DLL / MDd中使用MFC 发布:在共享DLL中使用MFC,/ MD

MDd和MD是相同的模式,但是一个链接与调试库有额外的调试信息。

然后你所能做的就是一次完成一个项目。请注意,如果按照建议创建新解决方案,则需要在项目之间重建依赖关系树。 (右键单击一个项目并选择'Dependencies',你会看到我的意思。)

当您遇到问题时,您应该与您工作场所的高级开发人员交朋友=)。

答案 2 :(得分:1)

使用相同的运行时库编译所有内容。故事结束。