I want to use the same #ifdef
approach used by WxWidgets , SDL etc. The only problem is I don't know how to use it.
Say I want to make a class that draws a rectangle. I want it to use cairo when on X11 platforms (i.e 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 would I use #ifdef
or something else to do this?
If you can, prefer to put platform specific methods into separate translation units. This will allow cleaner & more readable code and easier to develop and maintain. IMHO, the build process should determine which platform specific modules to incorporate.
For example:
rectangle.hpp:
struct Rectangle
{
void draw(int upper_left_corner_x, int upper_left_corner_y,
unsigned int length, unsigned int width);
}
Now the platform specific files:
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;
}
The above code has no conditional preprocessor directives. The main
function draws a rectangle regardless of the platform. The specifics of the platform have been removed from main
because they are not important. So, without changing any compiler switches or worrying about which preprocessor identifier is defined, one can see that main
unconditionally draws a rectangle.
To draw using a wxWidgets platform, the build process would use rectangle_wx_widgets.cpp
. To draw using QT, the rectangle_qt.cpp
file would be used, but not both. As this illustration shows, no code is changed in order to produce code for either platform. One could tailor the build process so the command build wxWidgets
would include the proper translation units. Thus passing a parameter to the build process generates the platform specific executable.
cross-platform doesn't mean only unix vs windows. also, the predefined cpp directives may be compiler dependent. boost platform selection source code is a good start to see how this can be done the right way. see config/select_platform_config.hpp you may also want to take a look at cmake which sets some platform dependent defines
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With