如何解决如何使用Xcode中的宏检测C ++编译器?
| 我正在将iOS项目中的Objective-C(* .m)和Objective-C ++(* .mm)源文件混合在一起。 当我在* .m文件中导入C ++头文件时,如何在头文件中排除特定于C ++的代码?我想使用一个编译器宏,例如:// SomeClass.h - a file I want to import in C++ and Objectice-C classes
#if CPLUSPLUS
#import \"CPlusPlusLibrary.h\"
#endif
@interface SomeClass : BaseClass
{
#if CPLUSPLUS
CPlusPlusClass* variable;
#endif
}
@end
解决方法
Objective-C ++是一种病毒,您无法真正停止。您当前的示例为您代码的不同部分(C和C ++)提供了类布局的不同视图,尽管我确实认为它仍然可以工作,但是我敢肯定这不是一件好事。
在处理与C ++交互的ObjC项目时,我通常会尝试避免在头文件中包含C ++引用。这使头文件对Objective-C和Objective-C ++均有效。如果我无法避免,那就不要尝试与之抗争(这是一个失败的事业);但是我尝试不要在其他\'sane \'ObjC头文件中包含该ObjC ++头文件,如果需要引用该类,则改用
@class
指令(@class SomeObjCPPClass;
而不是#import \"SomeObjCPPClass.h\"
指令)。然后,我包含实现文件中的标头,该标头必须是ObjC ++,但至少它不会从那里传播。
编辑Clang的最新版本(2012年及更高版本)允许您在事物的@implementation
侧声明字段。这可以有效地释放您对C ++的任何引用的标头,并使Objective-C ++更加易于管理(并减少病毒性)。为了保留OP的示例,您现在将拥有:
// SomeClass.h - a file I want to import in C++ and Objectice-C classes
@interface SomeClass : BaseClass
// (no fields)
// (methods)
@end
// SomeClass.mm
#import \"CPlusPlusLibrary.h\"
@implementation SomeClass
{
CPlusPlusClass* variable;
}
// (method implementations)
@end
这使得SomeClass.h标头可以安全地包含在纯Objective-C文件和Objective-C ++文件中。
,这将严重失败,因为SomeClass实例的大小和布局会有所不同,具体取决于它是从.m还是.mm文件编译而来的。
这是我的操作(添加了代码,使其也可以包含在.c和.cp中):
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#endif
#ifdef __cplusplus
#include \"CPlusPlusLibrary.h\"
#endif
#ifdef __cplusplus
class CPlusPlusClass;
#else
typedef struct CPlusPlusClass CPlusPlusClass;
#endif
#ifdef __OBJC__
@class AnotherObjCClass;
@interface SomeObjCClass : NSObject
{
CPlusPlusClass* _variableCPP;
AnotherObjCClass* _variableObjC;
}
#else
typedef struct ObjC_AnotherObjCClass AnotherObjCClass;
typedef struct ObjC_SomeClass SomeObjCClass;
#endif
#ifdef __cplusplus
extern \"C\" { // Callable from C
#endif
void CFunctionTakingCPlusPlusClass(CPlusPlusClass* foo);
void CFunctionTakingSomeObjCClass(SomeObjCClass* foo);
#ifdef __cplusplus
}
#endif
请注意,在编译.mm文件时,同时定义了__OBJC__和__cplusplus。 #include和#import在Objective-C(C-99的超集)中大致等效,但是对于C / C ++可见的任何内容,都必须使用#include。
请记住,在C中,从未定义过foo的struct foo*
(指向匿名结构的指针)是一个完全有效的类型,因此它所做的是将typedef \“ other language classes \”作为匿名结构,您可以通过指针进行传递而无需查找在内容上。
我将保留一个练习,它如何与ObjC实例变量的ARC交互。 (可能有龙和/或您可能需要__unsafe_unretained)
IIRC,如果对结构使用与C ++类相同的名称,则调试器将显示正确的信息(如果有)。我不确定Obj-C是否安全,因此我使用了其他名称。
另外,请尝试避免包括C ++标头(只需将其包含在.mm实现文件中),除非您需要匿名类以外的其他类型的标头。或者,您可以为其创建一个包装头,看起来像此文件的顶部。
HTH-史蒂夫
,当编译为c ++时,定义了一个预定义的宏:__cplusplus
我猜对于目标c ++也是一样。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。