簡體   English   中英

如何在Xcode中用宏檢測C ++編譯器?

[英]How to detect C++ compiler with macro in Xcode?

我在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

那會很糟糕,因為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* (指向匿名結構的指針)是一個完全有效的類型,所以它的作用是將“其他語言類”作為匿名結構,你可以通過指向w / o查看傳遞在內容上。

我將作為練習留下如何與ARC交互ObjC實例變量。 (可能有龍和/或你可能需要__unsafe_unretained)

IIRC,如果您使用與C ++類相同的結構名稱,調試器將顯示正確的信息(如果它可用)。 我不確定這對Obj-C是否安全,所以我使用了不同的名字。

另外,盡量避免包含C ++標頭(只需將它包含在.mm實現文件中),除非您需要匿名類以外的類型。 或者,您可以為它創建一個類似於此文件頂部的包裝器標頭。

HTH,-Steve

Objective-C ++是一個病毒式的東西,你無法真正停止。 您當前的示例為您的代碼的不同部分(C和C ++)提供了類的布局的不同視圖,雖然我認為它仍然可以工作,但我很確定這不是一件好事。

在處理與C ++交互的ObjC項目時,我通常會盡量避免在頭文件中使用C ++引用。 這使得頭文件對Objective-C和Objective-C ++都有效。 如果我無法避免它,那么我就不會試圖對抗它(這是一個失敗的原因); 但我嘗試不將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 ++文件中。

在編譯為c ++時,有一個預定義的宏定義: __cplusplus我猜對於目標c ++也是如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM