我正在编写一个包含C ++组件的iOS应用程序。为了获得主要包,许多其他答案建议使用:
CFBundleRef mainBundle = CFBundleGetMainBundle();
这很好,但似乎我必须包含类似
的内容#include <UIKit/UIKit.h>
位于我的文件顶部。但这样做会引发一系列错误,如:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:494:9: Unknown type name 'NSString'
我认为这与我的C ++代码有关。我想知道是否还有其他我可以包含哪些内容并不会引发此错误?如果没有,在C ++代码中访问文件路径的正确方法是什么?
答案 0 :(得分:2)
您可以尝试仅包含CoreFoundation
#include <CoreFoundation/CoreFoundation.h>
或者甚至只有CFBundle
#include <CoreFoundation/CFBundle.h>
答案 1 :(得分:0)
关键是 - 当您尝试#include
时 - 它认为代码是Native C或C ++。如果是这样,您需要告诉预处理器仅在#ifndef ...
包含它一次。
如果您计划混合使用C ++和Objective C代码 - 请使用#import
代替#include
,并且您需要使用此类从.m
到.mm
重命名所有文件延期。
最后一个。我确信NSString
是必须导入的NSFoundation
或CoreFoundation
的一部分 - UIKit
不对NSObject
个对象负责。
答案 2 :(得分:0)
这是由于C&#34;编译单元&#34;的概念。基本上,您在源文件中包含的所有标头都必须使用该文件的语言编写。由于Objective C和C ++都是(大致)C的超集,因此可以在C ++和Objective-C源文件中包含C头(如CoreFoundation)。
但是,C ++编译器不知道如何读取Objective-C文件,而Objective-C编译器不知道如何读取C ++文件,所以如果你从C ++中包含像UIKit这样的Objective-C头文件文件,C ++编译器会给你很多错误信息。
要避免此问题,您应该查找CFBundle的文档。事实证明,CFBundle是CoreFoundation的一部分,它是一个C API,因此可以很容易地从C ++文件调用,你只需要包含正确的标题。
虽然包含UIKit可能也有效,但这只是UIKit的某些部分基于CoreFoundation并使用它的事实的副作用,因此包括CoreFoundation。
但是,并非所有API都可用作C版本。如果你想从UIKit或AVFoundation左右调用某些东西,你可能需要创建一个C&#34;包装函数&#34;做你想做的事情,内部是在Objective C中实现的。只要你确保只有.m
实现文件包含Objective-C,并且头文件只暴露函数和标准C数据类型比如int或bool,你可以从C ++应用程序中调用函数,就像你使用任何其他普通的C函数一样(可能需要像使用常规C一样使用extern "C"
)。
还有一些名为&#34; Objective-C ++&#34; (文件后缀.mm
),这是一种&#34;伪语言&#34;这使得你可以在实现文件中混合使用Objective-C和C ++,但即使这样,你也必须注意不要在头文件中暴露任何Objective-C,以便能够从普通的C ++文件中调用它。
答案 3 :(得分:0)
出于某种原因,CFBundleRef
不是 C++ 中的完整类型,我是这样做的:
#include <CoreFoundation/CFBundle.h>
std::string get_resources_dir()
{
CFURLRef resourceURL = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
char resourcePath[PATH_MAX];
if (CFURLGetFileSystemRepresentation(resourceURL, true,
(UInt8 *)resourcePath,
PATH_MAX))
{
if (resourceURL != NULL)
{
CFRelease(resourceURL);
}
return resourcePath;
}
}