私は、その時点で使用しているapiに応じて、特定のコードのみを実行するための一般的で使いやすい方法を考え出そうとしています。
ヘッダー内:
#define __API_USED cocos2d-x
#define COCOS2DX cocos2d-x
#define OPENGL opengl
#ifdef __API_USED == COCOS2DX
#define USING_COCOS2DX
#undef USING_OPENGL
#endif
ソースで:
#ifdef USING_COCOS2DX
......
#endif
しかし、私はこれがうまくいくとは思いません。
私がやろうとしていることを達成する方法はありますか?
できますが、次のようにする必要があります。
#define __API_USED COCOS2DX
#define COCOS2DX 1
#define OPENGL 2
#if __API_USED == COCOS2DX
#define USING_COCOS2DX
#undef USING_OPENGL
#endif
Keith Thompsonが説明したように、cocos2d
やx
などの未定義のトークン(マクロ)は0
に評価されるため、使用しているマクロの値を定義する必要があります。
これを正しく理解していれば、cocos2d-x
はいくつかの可能なAPIの1つです。
プリプロセッサは、シンボルが定義されているかどうかをテストでき(#ifdef
およびdefined
演算子を使用)、定数整数式を評価できます(#if
を使用)。
1つのアプローチは、各APIの数値コードを定義することです。
#define COCOS2X 1
#define ANOTHER_API 2
#define YET_ANOTHER_API 3
/* ... */
その後:
#define API_USED COCOS2DX
#if API_USED == COCOS2DX
#define USING_COCOS2DX
#undef USING_OPENGL
#Elif API_USED == ANOTHER_API
/* ... */
#Elif API_USED == YET_ANOTHER_API
/* ... */
#endif
マクロ名を__API_USED
からAPI_USED
に変更したことに注意してください。 2つのアンダースコアで始まる(またはアンダースコアの後に大文字が続く)識別子は、すべての目的で実装用に予約されています。独自のコードでそれらを定義するべきではありません。
このアプローチの欠点の1つは、スペルミスのフラグが立てられないことです。プリプロセッサは、未定義の識別子を定数0
で静かに置き換えます。
APIごとに識別子を設定し、そのAPIが使用されている場合にのみ定義することをお勧めします。
#define USING_COCOS2X
/* #undef USING_COCOS2X */
その後:
#if USING_API_COCOS2X
#undef USING_OPENGL
#endif
マクロが定義されているかどうかのテストは、特定の値があるかどうかのテストよりも堅牢になる傾向があります。
次に、USING_API_*
マクロ(複数ある場合)が一貫して定義されていることを確認する必要があります。
これは、clang 8.1.0(Xcode 8.3.2から)で機能します。ヘッダーファイルで、値CONFIG
についてspecial
をテストするとします。特定の変換単位では、CONFIG
が設定されていないか、special
に設定されているか、別の値に設定されている可能性があります。
_#define CAT_HELPER(lhs, rhs) lhs##rhs
#define CAT(lhs, rhs) CAT_HELPER(lhs, rhs)
#define TEST_PREFIX_special 1
#if CAT(TEST_PREFIX_, CONFIG)
#pragma message("detected CONFIG == 'special'")
#else
#pragma message("CONFIG != 'special'")
#endif
_
二重間接参照(CAT()
はCAT_HELPER()
を呼び出します)は重要です。
この戦術は、未定義のマクロを_#if
_として展開する_0
_に依存しています。