【问题标题】:Undefined symbols for architecture arm64 after linking a static library in iOS app在 iOS 应用程序中链接静态库后架构 arm64 的未定义符号
【发布时间】:2020-07-09 18:54:10
【问题描述】:

我正在创建一个示例静态库以在我的 iOS 应用程序中使用,但是,在调用静态库的方法时,我遇到了链接器错误:

Undefined symbols for architecture arm64:
"_doMath", referenced from:
  _doMathInterface in libTestMain.a(Test.o)
 (maybe you meant: _doMathInterface)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

这是静态库的结构:

我有一个头文件Test.h:

#import <Foundation/Foundation.h>

@interface Test : NSObject

int doMathInterface(int a, int b);

@end

及其实现Test.m:

#import "Test.h"
#include "PaymentAPI.h"

@implementation Test

int doMathInterface(int a, int b){
    return doMath(a, b);
}

@end

在 PaymentAPI.h 中:

#ifndef PaymentAPI_h
#define PaymentAPI_h

int doMath(int a, int b);

#endif /* PaymentAPI_h */

终于在 PaymentAPI.cpp 中:

#include <stdio.h>
#include "PaymentAPI.h"

int doMath(int a, int b){
    return a + b;
}

正如您所见,它是一个非常简单的静态库,但我无法弄清楚为什么会发生此链接器错误,我已在应用程序的 Build Phases 的“Link Binaries with Libraries”中添加了静态库。

这是应用文件的截图:

我相信构建设置中的搜索路径配置也是正确的:

这是静态库项目的一些构建设置的屏幕截图

构建阶段:

架构:

非常感谢。

【问题讨论】:

    标签: c++ ios xcode static-libraries


    【解决方案1】:

    问题在于您的 doMath 函数被编译为 C++ 代码,这意味着函数名称被 C++ 编译器破坏。但是,您的 Test.m 文件会被(Objective-)C 编译器使用,并且 C 不使用名称修饰。

    这意味着链接器最终会寻找错误的符号。您可以通过让 C++ 编译器发出未损坏的函数名称来解决此问题。为此,您必须像这样在 PaymenAPI.h 中使用extern "C"

    #ifndef PaymentAPI_h
    #define PaymentAPI_h
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    int doMath(int a, int b);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* PaymentAPI_h */
    

    要获得完整的解释,您可以查看这个 SO 问题和接受的答案:Combining C++ and C - how does #ifdef __cplusplus work?

    【讨论】:

      【解决方案2】:

      当您通过 Objective-C 调用 C++ 函数时,您必须创建包装类(.mm 文件)。

      Please refer this link

      【讨论】:

        【解决方案3】:

        如果你想用 C++ 做静态库,你最好使用 djinni,因为它会处理包括函数名称和符号在内的桥接功能。

        【讨论】:

          【解决方案4】:

          链接器看到符号名称“_doMath”而不是“doMath” - 所以我认为您没有正确执行互操作。

          我发现了这个:mixing-objective-c-and-c 这是一篇很好的文章,它解释了如何在 C++ 和 ObjectiveC / ObjeciveC++ 之间进行互操作:

          https://www.drdobbs.com/cpp/interoperating-between-c-and-objective-c/240165502

          => 尝试将您的 .m 文件重命名为 .mm

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-06-18
            • 1970-01-01
            • 2016-01-08
            • 1970-01-01
            • 1970-01-01
            • 2013-10-13
            相关资源
            最近更新 更多