0

我正在我的 Mac 上构建一个基于 Windows 的项目。我已经修复了很多错误,但是当我去编译时,它给出了以下错误:

    Undefined symbols for architecture x86_64:
  "Timer::reset()", referenced from:
      Timer::Timer() in main.o
  "Log::Log()", referenced from:
      __static_initialization_and_destruction_0(int, int)in main.o
  "Log::~Log()", referenced from:
      ___tcf_1 in main.o
  "Render::initSDL(int, int, int)", referenced from:
      init()    in main.o
  "Log::writeError(char*, ...)", referenced from:
      init()    in main.o
      _SDL_main in main.o
  "EntityManager::init(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)", referenced from:
      init()    in main.o
  "EntityManager::loadAssets()", referenced from:
      init()    in main.o
  "Level::getBlockCount()", referenced from:
      EntityManager::getBlockCount()       in main.o
  "Level::getBombCount()", referenced from:
      EntityManager::getBombCount()       in main.o
  "Level::getItemCount()", referenced from:
      EntityManager::getItemCount()       in main.o
  "Render::renderElement(int, int, SDL_Surface*, SDL_Rect*)", referenced from:
      renderScene()     in main.o
  "EntityManager::getElement(int, ElementType)", referenced from:
      renderScene()     in main.o
  "Render::finishRender()", referenced from:
      renderScene()     in main.o
  "EntityManager::update()", referenced from:
      _SDL_main in main.o
  "EntityManager::interpolate(double)", referenced from:
      _SDL_main in main.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

我很好奇为什么它只引用了几个函数?这些功能是否包含非 Mac 兼容的内容?

例如:

int Level::getItemCount()
{
    return itemVec.size();
}

itemVec 是一个向量,只是为了清楚。

谢谢

4

2 回答 2

0

看起来您没有链接到 SDL 框架或库(但是它是打包的)。

在 Xcode 中,单击您的项目(文件树视图的顶部),然后单击您的 Target。然后单击摘要选项卡。这就是您要添加 SDL 框架的地方。

(如果它以 .lib 的形式出现,则需要向链接器添加一个额外的标志,例如“-lsdl”)。

与 SDL 链接应该处理您未解决的外部问题。

于 2012-07-15T03:51:36.427 回答
0

如果遇到链接器错误,则意味着编译器可以找到声明,但链接器找不到定义

我想你已经知道了,但以防万一:

对于一个方法,声明只是它的签名,例如:

class foo 
{
    public:
        void bar(); 
}

那是方法“void Foo::bar()”的声明,它进入头文件(.h,.hpp,...)

现在这个方法的定义也包含了主体。它必须与声明相匹配。同样的例子:

void Foo::bar()
{
std::cout << "Hello, world !" << std::endl;
}

那是方法“void Foo::bar()”的定义,它(通常)进入源文件(.cpp,.cxx,...)

在您的情况下,编译器找到了声明,但链接器没有找到定义。因此,您必须找到 Timer::reset() 的定义位置,并检查该位置是否可用于链接器。

最典型的原因是 Timer::reset() 是在 cpp 文件中定义的,并且该文件未包含在您的 xcode 项目中(别担心,如果您没有良好的构建配置工具,例如 Premake、Cmake 或其他...)

在这种情况下,将声明符号,因为您的代码中有某个地方 #include "timer.h" 或类似的东西,但未定义,因为匹配的 cpp 未包含在您的项目中。它(可能)存在于您的硬盘上,但未在您的项目中引用。

要解决这个问题:

  1. 查找 Timer::reset 的定义位置
  2. 如果它没有在任何地方定义,那么你就发现了你的问题。如果它被调用,它必须被定义
  3. 如果已定义,请检查 cpp 是否包含在您的项目中,与 main.cpp 位于同一模块中

您提到它仅针对特定功能发生。我可能会补充一点,如果从未调用过函数,您将不会收到错误消息。您是否只有在 main.cpp 中实际调用的函数才会收到此错误消息?

更多细节 :

据我所知(我可能错了,因为这不是我通常遇到的情况)编译器一次处理一个文件,声明但未定义的东西是完全合法的(毕竟它可以在另一个文件中定义)在编译阶段

链接器将所有文件放在一起,因此如果使用了符号(在您的情况下称为)并且未定义,他肯定会抱怨。

高温高压

于 2012-07-15T03:40:59.243 回答