MEGAEDIT 3000
我发现了未定义引用的原因。我检查了我的 .o 文件中的符号,它们只是丢失了。只是不在那里。没有明显的原因。我已经检查了妥协的 .o 文件的来源,但一切似乎都很好。我认为它可能是那些讨厌的#ifdef ... #endif
块之一,像熊陷阱一样巧妙地隐藏在代码行中,等待它的受害者。但我找不到任何东西。在将一些函数定义移动到文件的最后并将它们包含在#ifdef ... #endif
适合 Linux 的块中之后,符号神奇地出现了,一切都很好。感谢您的时间。
过时了,不读。
我最近被分配到一个大项目,我的工作是让它在 Linux 平台上运行。不幸的是,在我之前编写整个项目的程序员做得很差,通过包含
B3D_Base.h
几乎每个头文件所在的文件来创建大量循环依赖项#included
,到项目中的几乎每个头文件和源文件(这使得 170 多个文件与#include "B3D_Base.h"
线)。这在 Windows 和 Linux 上的编译期间都没有引起任何问题。但是,这会在 Linux 上的链接阶段导致大量“未定义引用”错误,即使所有目标文件和库都已链接。
意识到ld
在链接期间对所有目标文件进行单次迭代的限制,我在问:
有没有办法强制ld
通过对象和库进行多次迭代,可能解决所有 700 多个未定义的引用错误,或者是我唯一的机会实际链接项目只是用#include "B3D_Base.h"
正确的包含替换所有行到所需的标题?
附录1:
这是我应该在 Linux 上运行的混乱示例:
有一个头文件B3D_Base.h
,包含在其中B3D_Loading3.h
,其中包含 class B3D_LOADING3
. 文件B3D_Loading3.cpp
仅B3D_Base.h
包含,Base 中不包含内存管理器类。在项目的许多其他部分中B3D_LOADING3 g_Loading3;
声明并初始化+使用了一个实例。B3D_Base.h
一切都编译得很好,但是在链接方面,我遇到了很多'undefined reference to g_Loading3'
错误。还有更多这样的错误,抱怨对类实例和函数的未定义引用。干净的代码就这么多。
附录#2:
根据 kfsone 的要求,我将提供一个 SSCCE 示例:
B3D_Base.h
... (many other includes)
#include "B3D_Loading3.h"
extern B3D_LOADING3 g_Loading3;
... (includes go on)
B3D_Loading3.h/B3D_Loading.cpp
a full definition of class B3D_LOADING3, but no real declaration of g_Loading3
AW_Game.cpp(使用 g_Loading3 的文件之一)
#include "B3D_Base.h"
... (some lines)
extern B3D_LOADING3 g_Loading3;
感谢 kfsone 让我彻底检查代码,我设法找出问题所在: g_Loading3 到处都定义为extern
,因此没有正确定义。我所需要的只是extern
从一个文件中删除关键字。修复了我 ~ 30 个链接错误。谢谢,kfsone。
附录#3:
但是对类函数的未定义引用仍然存在问题。经过一些代码扫描后,我认为由于过度使用#ifdef ... #endif
子句(可移植性),甚至没有定义函数,因此可能是我的错,忽略了仅在某些被动 ifdef 块中定义的函数。我将尝试查看此问题,稍后报告是否有任何变化。
附录#3 报告:
即使在正确定义函数之后,未定义引用列表也没有缩小。因此,这个问题仍有待讨论。
附录#3.1
我将提供一些示例代码。
Foo.h
#ifndef FOO_H
#define FOO_H
class Foo
{
unsigned int m_size;
bool m_lock;
friend class ASDF;
public:
unsigned int m_id;
void Release() {delete this;}
int Lock(UINT OffsetToLock, UINT SizeToLock, VOID ** ppbData, DWORD Flags);
int Unlock();
};
// other class declarations to follow
#endif
Foo.cpp
#include "Foo.h"
// other includes and function definitions to follow
int Foo::Lock(UINT OffsetToLock, UINT SizeToLock, VOID ** ppbData, DWORD Flags)
{
if(!m_lock)
{
// some locking code
}
return 0;
}
巴兹.cpp
#include "Foo.h" // although included, defined and declared, causes undef reference
Foo *m_pFoo;
// several lines later
m_pFoo->Lock(0,0,(void)&Asdf,NULL); // <-- compiles fine, causes undefined reference