在Xcode的Swift项目上使用C ++时出错:体系结构x86_64的未定义符号

时间:2018-12-06 12:34:33

标签: c++ swift xcode macos objective-c-swift-bridge

网络上对此有很多疑问,但我无法解决问题。我已经研究了几天。

我想在Swift项目上运行一个简单的C ++类,为此我遵循了本教程:http://www.swiftprogrammer.info/swift_call_cpp.html。 基本上,我已经遵循了以下步骤:

  1. 创建junk.cppjunk.h文件
  2. 使用g++ or/and clang++
  3. 进行编译
  4. 使用以下文件创建一个文件:$ ar r libjunkcpp.a junk.o
  5. ranlib libjunkcpp.a
  6. 链接到Build Phases -> Link Binary With Libraries -> Add中的Xcode

编译时,出现以下错误:

Undefined symbols for architecture x86_64:
  "A::getInt()", referenced from:
      _getIntFromCPP in wrapper.o
  "A::A(int)", referenced from:
      _getIntFromCPP in wrapper.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
  

junk.h

class A {
    public:
    A(int);
    int getInt();

    private:
    int m_Int;
};
  

junk.cpp

#include "junk.h"

A::A(int _i) : m_Int(_i) {}

int A::getInt() {
    return m_Int
}
  

wrapper.cpp

#include "junk.h"

extern "C" int getIntFromCPP() {
    // Create an instance of A, defined in
    // the library, and call getInt() on it:
    return A(1234).getInt();
}
  

bridge.h

int getIntFromCPP();

1 个答案:

答案 0 :(得分:0)

这是在使用通过 Objective-C 桥接到 Swift 的 C 或 C++ 库时有时会发生的问题。问题不在于存档(静态库)的构建方式,而是创建应用程序的过于激进的链接器的问题。

问题是链接器看到绑定符号和 C++ 符号,但从未看到它被从任何地方调用,因为它实际上是从不同的语言 (Swift) 调用的。这最终会导致链接器积极地剥离所有它认为不会被使用的符号以节省空间,从而有效地删除所有 C++ 代码。

发生这种情况时,nm 将报告存档中存在的正确符号,但由于找不到符号,实际应用程序将无法执行。


至于解决方案,实际上 Stack Overflow 上已经有几个问题/答案在不同程度上解决了这个问题:

如果没有关于现有设置的更多信息,例如 __attribute__((constructor)) 在哪里构建,以及如何在 Swift 项目中使用绑定,很难提供明确而明确的答案。鉴于这个问题是从 2018 年开始的,我不怀疑会有更多关于当时这种设置的信息。

从描述的症状来看,这听起来与我的同事在进行 C++/Swift 绑定时遇到的问题完全一样——最终的解决方案是使用 wrapper.cpp 来确保存档完整地保留到最终应用程序中.