2011-11-10 8 views
5

WxWidgets、SDLなどで使用されている同じ#ifdefアプローチを使用したいと思います。唯一の問題は、どのように使用するのかわかりません。クロスプラットフォームライブラリの作成にどのようにプリプロセッサを使用しますか?

私は矩形を描くクラスを作ってみたいと思います。私は、Win32プラットフォーム上では、X11プラットフォーム(すなわちLinux)の上のときカイロを使用したいとGDI:

class graphics 
{ 
void drawRect(int x, int y, int w, int h) 
{ 
/*if on win32*/ 
HDC myHdc = ::BeginPaint(myHwnd,&mypstr); 
::Rectangle(myHdc,x,y,w,h); 
::EndPaint(myHwnd,&mypstr); 

/*if on x11*/ 
cairo_surface_t* s = cairo_xlib_surface_create(/* args */); 
cairo_t* c = cairo_create(s); 
cairo_rectangle(c,x,y,w,h); 
// etc. etc. 
} 
}; 

は、どのように私はこれを行うには#ifdefまたは何か他のものを使用するのでしょうか?

+0

探しているプリプロセッサの例をWxWidgetsやSDLで提供しないでください。 –

+1

(+1)質問タイトルによって表される概念は、アップヴォートの価値があります。答えを持っていない、他の開発者の回答を読む... – umlcat

答えて

3

することができます場合関連項目別々の翻訳単位。これにより、より洗練されたコード&が読みやすくなり、開発と保守が容易になります。 IMHO、ビルドプロセスは、組み込むプラットフォーム固有のモジュールを決定する必要があります。
rectangle.hpp:今

struct Rectangle 
{ 
    void draw(int upper_left_corner_x, int upper_left_corner_y, 
      unsigned int length, unsigned int width); 
} 

プラットフォーム固有のファイル:
rectangle_wx_widgets.cpp:

#include "rectangle.hpp" 
void 
Rectangle :: 
draw(int upper_left_corner_x, int upper_left_corner_y, 
      unsigned int length, unsigned int width) 
{ 
// wxWidgets specific code here. 
} 

rectangle_qt.cpp:

例えば

#include "rectangle.hpp" 
void 
Rectangle :: 
draw(int upper_left_corner_x, int upper_left_corner_y, 
      unsigned int length, unsigned int width) 
{ 
// QT specific code here. 
} 

main.cppに:

#include "rectangl.hpp" 
int main(void) 
{ 
    Rectangle r; 
    r.draw(50, 50, 10, 5); 
    return 0; 
} 

上記のコードには、条件付きプリプロセッサディレクティブを有していません。 main関数は、プラットフォームに関係なく長方形を描画します。プラットフォームの仕様は重要ではないため、mainから削除されました。したがって、コンパイラスイッチを変更したり、どのプリプロセッサ識別子が定義されているかについて心配することなく、mainが無条件に矩形を描画することがわかります。

wxWidgetsプラットフォームを使用して描画する場合、ビルドプロセスはrectangle_wx_widgets.cppを使用します。 QTを使用して描画するには、rectangle_qt.cppファイルが使用されますが、両方は使用されません。この図に示すように、いずれのプラットフォームのコードを生成するためにコードは変更されません。コマンドbuild wxWidgetsに適切な翻訳単位が含まれるように、ビルドプロセスを調整することができます。したがって、パラメータをビルドプロセスに渡すと、プラットフォーム固有の実行可能ファイルが生成されます。

+0

私はあなたのソリューションがきれいに見えることに同意します。 (+1)が、私は1つまたは2つの問題を感じる、私はヘッダーの何かを変更したい場合はどうすればいいですか?たとえば、 windowsの場合typedef HDCペインタその他else typedef cairo_t painter – ApprenticeHacker

+0

@IntermediateHacker:プラットフォーム固有のファイルには、プラットフォーム固有のヘッダを含めることができます。あなたの応答の例では、フレームワーク固有の汎用の 'paint'メソッドを作成します。 Windows API用の 'paint'とCairo用の' paint'があります。これを可能な限り伝播させてください。目的は、条件付きプリプロセッサ指令の数を減らすことです。 –

+0

ありがとうございます。あなたのソリューションは完璧に動作します。 – ApprenticeHacker

0

非常に直接的です。

#ifndef WIN32 
// something for X11 
#else 
// something for Windows 
#endif 

それは(この場合はWIN32のような)デフォルトの条件文を知るだけです:

あなたはこのような何かをしたいです。オペレーティングシステム、コンパイラ、および移植性の高いものには条件があります。

この場合は、windows.hヘッダーファイルを参照してください。それはあなたのためのより多くの情報を含むかもしれません。

+0

あなたはおそらく 'ifdef'を望んでいるので、2つ以上をサポートすることができます。 –

0

あなたが使用することができWIN32のような事前に定義されたプラットフォームの変数があります。

#ifdef WIN32 
.... 
#else 
.... 
#endif 
2

クロスプラットフォームはUNIXとWindowsの両方を意味するものではありません。また、定義済みのcppディレクティブはコンパイラに依存している可能性があります。 プラットフォーム選択のソースコードを改善することは、これがどのように正しい方法で行われるかを見る良いスタートです。あなたはまた、いくつかのplatform dependent defines

+0

"unix vs windows"の意味で申し訳ありませんが、意図されていませんでした。私はその点について説明したがっています。 – ApprenticeHacker

+1

馬鹿を意図していない、私はちょうど私のポイントを作っていた – user237419

+0

その後問題はありません。 (+1):) – ApprenticeHacker

0

私は他の人が(:sysfaultはそれを言及した編集を)言及表示されていないこと、それにトリックがありますが設定されますcmakeを見てみたいことがありconfig/select_platform_config.hpp を参照してください。ここには2つの異なる概念があります。プリプロセッサのコマンドは、ターゲットとコンパイラによって異なります。つまり、あなたが使っているどのコンパイラ(MSVCGCC

#ifdef _MSC_VER 
    /*MSVC*/ 
#endif 
#ifdef __GNUC__ 
    /*GCC*/ 
#endif 

を伝えるためにMSVCは、Windowsターゲット(限り、我々は今日懸念しているとして)用にコンパイルし、GCCはすべてを対象としています。 GCCの場合は、を伝えるためにそれがターゲットだどの OS:

#ifdef __MINGW32__ 
    /* Windows */ 
#endif 
#ifdef BSD 
    /* BSD */ 
#endif 
#ifdef __linux__ 
    /* linux */ 
#endif 
#ifdef __APPLE__ 
    /* OSX */ 
#endif 

はまた、時々、あなたは、オペレーティング・システムのプロセッサに固有の何かを知っているが、ないようにする必要があります。

__CHAR_UNSIGNED__ 
    GCC defines this macro if and only if the data type char is unsigned on the target machine. 
__BYTE_ORDER__ 
__ORDER_LITTLE_ENDIAN__ 
__ORDER_BIG_ENDIAN__ 
__ORDER_PDP_ENDIAN__ 
    __BYTE_ORDER__ is defined to one of the values __ORDER_LITTLE_ENDIAN__, __ORDER_BIG_ENDIAN__, or __ORDER_PDP_ENDIAN__ to reflect the layout of multi-byte and multi-word quantities in memory. 
__LP64__ 
_LP64 
    These macros are defined, with value 1, if (and only if) the compilation is for a target where long int and pointer both use 64-bits and int uses 32-bit. 

そして、多くの他の多く

関連する問題