How to use a preprocessor to create a cross-platform library?

I want to use the same approach #ifdefused by WxWidgets, SDL, etc. The only problem is that I do not know how to use it.

Let's say I want to create a class that draws a rectangle. I want him to use cairo when on X11 platforms (like Linux) and GDI on win32 platforms:

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

How to use #ifdefor something else for this?

+5
source share
6 answers

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

+3

- unix vs windows. cpp . - , , . . config/select_platform_config.hpp cmake,

+2

.

- :

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

(, WIN32 ). , .

windows.h. .

0

, WIN32, :

#ifdef WIN32
....
#else
....
#endif
0

, (: sysfault ). . . , , (GCC vs MSVC)

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

MSVC Windows ( ), GCC . GCC, , :

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

In addition, sometimes you need to know something specific to the processor, but not to the operating system:

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

And many others

0
source

All Articles