在 iOS 应用程序中链接静态库后架构 arm64 的未定义符号
Undefined symbols for architecture arm64 after linking a static library in iOS app
我正在创建一个要在我的 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;
}
如您所见,它是一个非常简单的静态库,但我无法弄清楚为什么会出现此链接器错误,我已将静态库添加到构建阶段的“Link Binaries with Libraries”中在应用程序中。
这是 app 文件的屏幕截图:
构建设置中的搜索路径配置也是正确的,我相信:
这是静态库项目
的一些构建设置的屏幕截图
构建阶段:
架构:
非常感谢。
链接器看到符号名称“_doMath”而不是“doMath”——所以我认为你没有正确执行互操作。
我发现了这个:mixing-objective-c-and-c
这是一篇很好的文章,解释了如何在 C++ 和 ObjectiveC / ObjeciveC++ 之间进行互操作:
https://www.drdobbs.com/cpp/interoperating-between-c-and-objective-c/240165502
=> 尝试将您的 .m 文件重命名为 .mm
问题是您的 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?
当您通过 Objective-C 调用 C++ 函数时,您必须创建包装器 class(.mm 文件)。
Please refer this link
如果你想用 C++ 做静态库,你最好使用 djinni,因为它会处理桥接功能,包括函数名称和符号。
我正在创建一个要在我的 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;
}
如您所见,它是一个非常简单的静态库,但我无法弄清楚为什么会出现此链接器错误,我已将静态库添加到构建阶段的“Link Binaries with Libraries”中在应用程序中。
这是 app 文件的屏幕截图:
构建设置中的搜索路径配置也是正确的,我相信:
这是静态库项目
的一些构建设置的屏幕截图构建阶段:
架构:
非常感谢。
链接器看到符号名称“_doMath”而不是“doMath”——所以我认为你没有正确执行互操作。
我发现了这个:mixing-objective-c-and-c 这是一篇很好的文章,解释了如何在 C++ 和 ObjectiveC / ObjeciveC++ 之间进行互操作:
https://www.drdobbs.com/cpp/interoperating-between-c-and-objective-c/240165502
=> 尝试将您的 .m 文件重命名为 .mm
问题是您的 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?
当您通过 Objective-C 调用 C++ 函数时,您必须创建包装器 class(.mm 文件)。
Please refer this link
如果你想用 C++ 做静态库,你最好使用 djinni,因为它会处理桥接功能,包括函数名称和符号。