C++ 如何检测C++;在Xcode中使用宏的编译器?
我在一个iOS项目中混合了Objective-C(*.m)和Objective-C++(*.mm)源文件。 当我在一个*.m文件中导入一个C++头文件时,我如何排除头文件中的C++特定代码?我想使用编译器宏,类似于:C++ 如何检测C++;在Xcode中使用宏的编译器?,c++,objective-c,xcode,macros,objective-c++,C++,Objective C,Xcode,Macros,Objective 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 SomeC
// 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
<> P>有一个预定义宏,编译为C++:<代码>·yp+cPLUS PLUS < /COD> >我想对于目标C++也是如此。<> P> ObjultC++是一个病毒性的东西,你不能真正停止。您当前的示例为代码的不同部分(C和C++)提供了不同的类布局视图,虽然我确实认为它仍然可以工作,但我非常确定这不是一件很好的事情 <>当我在Objc项目中与C++交互时,我通常会尽量避免在头文件中使用C++引用。这使得头文件对Objective-C和Objective-C++都有效。如果我无法避免它,那么我就不会试图与之抗争(这是一个失败的事业);但我尽量不在其他“正常”的ObjC头文件中包含该ObjC++头文件,如果需要引用该类,我会使用
@class
指令(@class SomeObjCPPClass;
而不是#import“SomeObjCPPClass.h”
指令)。然后,我包含了实现文件中的头文件,它必须是ObjC++,但至少它不会从那里传播
EDITClang的最新ish(2012年及更高版本)版本允许您在@implementation
方面声明字段。这可以有效地释放任何引用C++的标题,使Objto-C++更易于管理(并且更少病毒)。要保留OP的示例,您现在需要:
// SomeClass.h - a file I want to import in C++ and Objectice-C classes
@interface SomeClass : BaseClass
// (no fields)
// (methods)
@end
这使得SomeClass.h头可以安全地包含在纯Objective-C文件和Objective-C++文件中。这将严重失败,因为SomeClass的实例将具有不同的大小和布局,这取决于它是从.m还是.mm文件编译的 下面是我将要做的(添加代码,使其也可以从.c和.cp中包含):
#ifdef_uuobjc__
#进口
#恩迪夫
#ifdef_uucplusplus
#包括“cplupluslibrary.h”
#恩迪夫
#ifdef_uucplusplus
类cpluplusclass;
#否则
typedef结构cpluplusclass cpluplusclass;
#恩迪夫
#ifdef__OBJC__
@类别另一个类别;
@接口someObjClass:NSObject
{
CPlusPlusClass*_变量CPP;
另一个OBJC类*_variableObjC;
}
#否则
typedef struct ObjC_另一个对象类另一个对象类;
typedef struct ObjC_SomeClass someObjClass;
#恩迪夫
#ifdef_uucplusplus
外部“C”{//可从C调用
#恩迪夫
无效CFunctionTakingCPlusPlusClass(CPlusPlusClass*foo);
无效cFunctionTakingSomeObjClass(SomeObjClass*foo);
#ifdef_uucplusplus
}
#恩迪夫
请注意,在编译.mm文件时,会同时定义uuu OBJC_uuu和uuu cplusplus#include和#import在Objective-C(C-99的超集)中大致相当,但对于C/C++可见的任何内容,都必须使用#include
请记住,在C语言中,一个从未定义过foo(指向匿名结构的指针)的struct foo*
是一个完全有效的类型,因此它的作用是将typedef“other language class”定义为匿名结构,您可以通过指针传递,而不必查看内容
我将把它与ARC for ObjC实例变量的交互留作练习。(可能有龙和/或您可能需要u不安全u未修复)
iRC,如果使用结构名作为C++类,则调试器将显示正确的信息,如果它可用的话。我不确定这对Obj-C是否安全,所以我使用了不同的名称
也尽量避免包含C++头(只包含在.mm实现文件中),除非您需要它用于匿名类之外的类型。或者,您可以为它创建一个类似于此文件顶部的包装头
Hth--史提夫
我比这个稍微多了一些,允许我自己在Objc头中声明C++类作为结构,这样我就可以在Objc类中包含指针,而不必知道Objc类需要Objc++。结构和类的不同之处在于成员的默认可见性,因此,将某个对象称为结构(实际上是类)的转发声明没有不良副作用,您的方法对我很有效,但当我调用objective-c++对象上的方法时,我收到一些警告:Receiver'SomeClass'是一个转发类,而相应的@interface可能不是exist@phix23你需要从你的实现文件<代码> >导入> /Obj> Objc++头。@ ZNEAK,但它不会编译,因为我在Objc++中有C++成员。头,相反,我可以用我需要的方法复制@接口(实现C++文件)来摆脱warning@phix23您还需要实现文件为Objective-C++。如果您将扩展名更改为.mm
,则一切都应该正常。ObjC++不会进一步传播,因为您的接口文件仍然是有效的Objective-C+感谢您包含所有ifdef宏。谢谢,我也在做类似的事情,我觉得值得留下一份锅炉板的副本,以便我能再次找到它。;-)
// SomeClass.mm
#import "CPlusPlusLibrary.h"
@implementation SomeClass
{
CPlusPlusClass* variable;
}
// (method implementations)
@end
#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