首页 > 解决方案 > 在 Xcode 上的 Swift 项目上使用 C++ 时出错:架构 x86_64 的未定义符号

问题描述

网上有很多关于这个的问题,但我无法解决我的问题。这几天我一直在研究这个。

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

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

当我编译时,出现以下错误:

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)

垃圾变种h

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

    private:
    int m_Int;
};

垃圾文件

#include "junk.h"

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

int A::getInt() {
    return m_Int
}

包装器.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();
}

桥接器

int getIntFromCPP();

标签: c++swiftxcodemacosobjective-c-swift-bridge

解决方案


这是在使用通过 Objective-C 桥接到 Swift 的 C 或 C++ 库时有时会出现的问题。问题不在于归档(静态库)是如何构建的——而是过度激进的链接器创建应用程序的问题。

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

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


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

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

从所描述的症状来看,这听起来与我的同事在进行 C++/Swift 绑定时所面临的问题完全一样——并且最终要使用的解决方案是-force_load确保将存档完整地保存到最终应用程序中。


推荐阅读