[英]Linker problem using Objective-C++ with Objective-C
目前我有一個使用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
但是,這很奇怪。 我選擇不使用.mm
擴展名為Util.m
類,因為我沒有使用任何C ++代碼。 另請注意, base11.h
頭文件也不使用任何C ++代碼。 那么,為什么我會收到此錯誤? 根據這篇文章,我的方法應該是正確的:
這是函數符號名稱中的問題。 C ++允許具有相同名稱和不同原型的函數。 因此,當使用C ++ / Objective-C ++編譯的函數時,它獲得了描述它原型的符號名稱並使其獨特。
所以你需要強制編譯器使用C的符號名稱。 你可以通過在函數原型之前添加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 */
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.