2011-11-10 15 views
5

Ben WxWidgets tarafından kullanılan aynı #ifdef yaklaşımı kullanmak istiyorum, SDL vb tek sorun nasıl kullanılacağını bilmiyorum edilir.Çapraz platform kitaplığı yapmak için önişlemciyi nasıl kullanıyorsunuz?

Dikdörtgen çizen bir sınıf yapmak istediğimi varsayalım.

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. 
} 
}; 

nasıl #ifdef kullanmak veya başka bir şey bunu yapmak için: Ben Win32 platformlarında zaman X11 platformlarında (yani linux) ve GDI üzerinde cairo kullanmak istiyorum?

+0

değil WxWidgets yapın ve SDL aradığınız önişlemci örnekler sunmak? –

+1

(+1) Soru başlığı ile temsil edilen kavram, bir kazanım anlamına gelir. Eğer ikiden fazla destekleyebilir böylece başkaları geliştiriciler cevapları ... – umlcat

cevap

3

Eğer yapabiliyorsanız ayrıca bkz ayrı çeviri birimleri. Bu daha temiz & okunabilir kod sağlar ve geliştirmek ve korumak için daha kolay olacaktır. IMHO, yapım süreci hangi platform özel modüllerinin dahil edileceğini belirlemelidir.
rectangle.hpp: Şimdi

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

platforma özel dosyalar:
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:

Örneğin

#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; 
} 

Yukarıdaki kod koşullu önişlemci direktifleri vardır. main işlevi, platformdan bağımsız olarak bir dikdörtgen çizer. Platformun özellikleri, önemli olmadıkları için main'dan kaldırılmıştır. Yani, herhangi bir derleyici anahtarını değiştirmeden veya hangi önişlemci tanımlayıcısının tanımlandığından endişe etmeden, main koşulsuz olarak bir dikdörtgen çizdiğini görebilirsiniz.

Bir wxWidgets platformu kullanarak çizmek için, oluşturma işlemi rectangle_wx_widgets.cpp'u kullanır. QT kullanarak çizim yapmak için rectangle_qt.cpp dosyası kullanılır, ancak her ikisi de kullanılamaz. Bu resimde gösterildiği gibi, her iki platform için de kod üretmek için hiçbir kod değiştirilmez.Biri, oluşturma işlemini uyarlayabilir, böylece build wxWidgets komutu, uygun çeviri birimlerini içerecektir. Böylece bir parametrenin yapıya geçirilmesi işlemi, platforma özgü yürütülebilir dosyayı oluşturur.

+0

Çözümünüzün daha temiz olduğunu kabul ediyorum. (+1), ama bir veya iki problemi hissediyorum, ne üstbilgideki bir şeyi değiştirmek istersem? örneğin HDC typedef pencereler 'painter' eğer başka' typedef cairo_t painter' – ApprenticeHacker

+0

@IntermediateHacker: Belirli dosyaları platforma özel başlıklar yer alıyor platformu. Yanıt örneğinizde, çerçeveye özgü bir genel "boya" yöntemi oluşturursunuz. Windows API için 'paint' ve Kahire için 'paint' olurdu. Ve bunu mümkün olduğunca uzağa yayıyoruz. Amaç, şartlı önişlemci direktiflerinin miktarını azaltmaktır. –

+0

Teşekkürler. Çözümünüz mükemmel çalışıyor. – ApprenticeHacker

0

Onlar oldukça doğrudan vardır.

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

O (bu durumda WIN32 gibi) varsayılan conditionals bilmenin meselesi:

Böyle bir şey istiyorum. İşletim sistemi, derleyiciler ve bir sürü taşınabilirlik maddesi için şartlar var.

Bu durumda, windows.h başlık dosyasına bakın. Sizin için daha fazla bilgi içerebilir.

+0

okuma bir cevap yok mu muhtemelen ifdef' 'istiyorum. –

0

kullanabilirsiniz WIN32 gibi önceden tanımlanmış bir platform değişken vardır:

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

çapraz platform pencereler vs sadece unix anlamına gelmez. Ayrıca, önceden tanımlanmış cpp yönergeleri derleyici bağımlı olabilir. boost platformu seçimi kaynak kodu bu doğru yolu yapılabilir görmek için iyi bir başlangıçtır. Ayrıca diğerleri söz görmüyorum buna bir numara yok bazı platform dependent defines

+0

"unix vs windows" imaları için özür dilerim, bu amaçlanmamıştı. Sadece bu noktayı açıklamak istedim. – ApprenticeHacker

+1

hiçbir cinas ben sadece o benim açımdan – user237419

+0

hiçbir sorun çıkıyordu, amaçlanan. (+1) :) – ApprenticeHacker

0

setleri cmake bakmak isteyebilirsiniz config/select_platform_config.hpp (bkz düzenlemek: Sysfault söz). Burada iki farklı kavram var. Önişlemci komutları hem hedefinize hem de derleyicinize göre farklılık gösterecektir. Yani, sen

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

MSVC sadece (bildiğim kadarıyla, bugün ilgilendiğinizden,), Windows hedefler için derleyip (GCCMSVC vs) kullanmakta olduğunuz derleyici anlatmak ve GCC şeyi hedefliyor etmek. İşletim sistemini

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

, bazen işlemciye belirli bir şey bilmek gerekir, ancak:

__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. 

Ve birçok diğerleri

GCC için, hedeflediğinden OS anlatmak
İlgili konular