目前我有一个使用 Objective-C 的 iOS 项目。出于性能原因,我实现了如下所示的 Objective-C++ 代码:
base11.mm
#include <string>
#include "base11.h"
static const std::string characters = "0123456789_";
const char* to_base11(long n) {
// some c++ code here
}
long from_base11(const char* input) {
// some c++ code here
}
base11.h
#ifndef base11_h
#define base11_h
#include <stdio.h>
const char* to_base11(long n);
long from_base11(const char* input);
#endif /* base11_h */
当然,我为该类使用了 .mm
扩展名,而且我只使用普通的 C 函数参数和返回类型。
然后我有一个 Objective-C 类,它将这些 C++ 函数包装在以下方法中:
Util.m
#include "base11.h"
+(NSString*) convertBase10ToBase11:(long) base10 {
const char* base11 = to_base11(base10);
return [NSString stringWithUTF8String:base11];
}
+(NSNumber*) convertBase11ToBase10:(NSString*) base11 {
const char* input = [base11 UTF8String];
return @(from_base11(input));
}
和 Util.h:
@interface Util : NSObject
+(NSString*) convertBase10ToBase11:(long) base10;
+(NSNumber*) convertBase11ToBase10:(NSString*) base11;
@end
然而,这会产生以下编译错误:
Undefined symbols for architecture x86_64:
"_from_base11", referenced from:
+[Util convertBase11ToBase10:] in Util.o
"_to_base11", referenced from:
+[Util convertBase10ToBase11:] in Util.o
ld: symbol(s) not found for architecture x86_64
但是,这很奇怪。我选择不对 Util.m
类使用 .mm
扩展名,因为我不在那里使用任何 C++ 代码。另请注意,base11.h
头文件也未使用任何 C++ 代码。那么,为什么会出现此错误?根据这篇文章,我的方法应该是正确的:
最佳答案
这是函数符号名称的问题。 C++ 允许具有相同名称和不同原型(prototype)的函数。 因此,当使用 C++/Objective-C++ 编译的函数时,它会获得描述它原型(prototype)的符号名称并使其独一无二。
所以你需要强制编译器使用 C 的符号名。
您可以通过在函数原型(prototype)之前添加 extern "C"
来实现。
但是如果你在 C 和 C++ 源文件中都使用这个头文件就不太方便了,因为 C 不知道它是什么extern "C"
。
幸运的是 CoreFoundation
已经解决了这个问题。您可以查看他们是如何声明他们的 CFString.h
、CFArray.h
的。
所以你只需要使用 CoreFoundation 的宏:CF_EXTERN_C_BEGIN
和 CF_EXTERN_C_END
。
#ifndef base11_h
#define base11_h
#include <stdio.h>
#include <CoreFoundation/CFBase.h>
CF_IMPLICIT_BRIDGING_ENABLED
CF_EXTERN_C_BEGIN
const char* to_base11(long n);
long from_base11(const char* input);
CF_EXTERN_C_END
CF_IMPLICIT_BRIDGING_DISABLED
#endif /* base11_h */
关于c++ - 使用 Objective-C++ 和 Objective-C 的链接器问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53258343/