简体   繁体   English

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

[英]Error to use C++ on Swift project on Xcode: Undefined symbols for architecture x86_64

There are a lot of questions about this on the web but I couldn't solve my problem.网上有很多关于这个的问题,但我无法解决我的问题。 I've been studying this for a few days.我已经研究了几天了。

I want run a simple C++ class on Swift project, to this I followed this tutorial: http://www.swiftprogrammer.info/swift_call_cpp.html .我想在 Swift 项目上运行一个简单的 C++ 类,对此我遵循了本教程: http ://www.swiftprogrammer.info/swift_call_cpp.html。 Basically I've followed the steps:基本上我遵循了以下步骤:

  1. Create junk.cpp and junk.h files创建junk.cppjunk.h文件
  2. Compile using g++ or/and clang++使用g++ or/and clang++
  3. Create.a file with: $ ar r libjunkcpp.a junk.o创建一个文件: $ ar r libjunkcpp.a junk.o
  4. ranlib libjunkcpp.a
  5. Linked to Xcode in Build Phases -> Link Binary With Libraries -> AddBuild Phases -> Link Binary With Libraries -> Add

When I compiles, the follow errors occurs:当我编译时,出现以下错误:

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垃圾.h

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

    private:
    int m_Int;
};

junk.cpp垃圾.cpp

#include "junk.h"

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

int A::getInt() {
    return m_Int
}

wrapper.cpp包装器.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桥.h

int getIntFromCPP();

This is an issue that sometimes occurs when using C or C++ libraries that get bridged through Objective-C into Swift.当使用通过 Objective-C 桥接到 Swift 的 C 或 C++ 库时,有时会出现这个问题。 The issue isn't with how the Archive (static library) is built -- rather, it's a problem with an overly-aggressive linker creating the application.问题不在于 Archive(静态库)的构建方式——而是创建应用程序的过于激进的链接器的问题。

The problem is that the linker sees the binding symbols and the C++ symbols, but never sees it being called from anywhere because it is actually invoked from a different language (Swift).问题是链接器看到了绑定符号和 C++ 符号,但从未看到它从任何地方被调用,因为它实际上是从不同的语言 (Swift) 调用的。 This ultimately results in the linker aggressively stripping all symbols that it doesn't believe are being used in an effort to save space, which effectively removes all of the C++ code.这最终会导致链接器主动剥离所有它不认为正在使用的符号以节省空间,从而有效地删除所有 C++ 代码。

When this happens, nm will report the correct symbols as existing in the archive, but the actual application will fail to execute due to the symbols not being found.发生这种情况时, nm将报告存档中存在正确的符号,但实际应用程序将由于未找到符号而无法执行。


As for solutions, there are actually several questions/answers already on Stack Overflow that address this issue in varying degrees:至于解决方案,实际上 Stack Overflow 上已经有几个问题/答案在不同程度上解决了这个问题:

It is difficult to provide a definitive and clear answer without more information on the existing setup, such as where wrapper.cpp is built, and how the bindings get used from within the Swift project.如果没有有关现有设置的更多信息(例如构建wrapper.cpp的位置以及如何在 Swift 项目中使用绑定),则很难提供明确明确的答案。 Given that this question is from 2018, I don't suspect there will be much more information on what this setup was at the time.鉴于这个问题是从 2018 年开始的,我不怀疑会有更多关于当时的设置的信息。

From the described symptoms, this sounds exactly like the issue my colleagues faced when doing C++/Swift bindings -- and the solution was ultimately to use -force_load which ensures that the archive is preserved in totality into the final application.从所描述的症状来看,这听起来就像我的同事在进行 C++/Swift 绑定时遇到的问题——解决方案最终是使用-force_load以确保将存档完整保留到最终应用程序中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM