do you have any suggestion of a design pattern or technique for implementing a hardware abstraction layer in C++, so that I can easily switch between platforms at build time? I was thinking of using something like the bridge pattern I read about in GoF or C++ templates, but I'm not sure if this is the best choice.
Asked
Active
Viewed 2,085 times
2 Answers
2
I think it is not a good choice of using bridge pattern at build time.
This is my solution:
Define a standard device class as an interface:
class Device {
... // Common functions
};
For X86 platform:
#ifdef X86 // X86 just is an example, user should find the platform define.
class X86Device: public Device{
... // special code for X86 platform
};
#endif
For ARM platform:
#ifdef ARM // ARM just is an example, user should find the platform define.
class ARMDevice: public Device {
... // Special code for ARM platform
};
#endif
Using these Devices:
#ifdef X86
Device* dev = new X86Device();
#elif ARM
Device* dev = new ARMDevice();
#endif
Compile Option:
$ g++ -DARM ... // using ArmDevice
$ g++ -DX86 ... // using X86Device
-
4If anyway you know the target CPU in compile time, why resort to dynamic polymporphism? you lose from every side! – David Haim Mar 16 '17 at 11:09
-
Agreed! In addition, SFINAE over #ifdef – Jeff Mar 16 '17 at 11:13
-
X86 and ARM just is an example, You can replace these by PAX255, IT3354. To a device, the source code of driver for different platform is almost same except some key point just as initial process. I can write all of these codes for different platform in a class or in a file, but it's not a good choice in aspect of code maintenance @DavidHaim – netdigger Mar 16 '17 at 11:29
-
1@netdigger and yet, there is no reason to use dynamic polymorphism when you know the CPU on compile time. the class interface can be the same while the implementation is different. – David Haim Mar 16 '17 at 11:38
-
1a `pubic` Device?!... that's gross :P – JHBonarius Mar 16 '17 at 11:45
-
2Thank you for the input guys. I'll probably implement it with conditional compilation and without the interface... But I think I will still resort to the bridge to decouple the class with management logic, from the class actually messing with the hardware. BTW, @Jeff , could you elaboration in what you mean by "SFINAE over #ifdef" ? – josecm Mar 16 '17 at 11:49
-
If there's only a derived class from the base class the compiler/linker can devirtualize, and where it can't processors smart enough will always predict the branch correctly - the only cost becomes missed opportunity for inlining. Still, I don't see why you can't resolve it at compile time by changing the type of `dev` to the type of device actually used in this compilation (a `typedef` can be useful). You can keep the class hierarchy for clarity and to share code between derived classes, but always use the concrete type in the rest of the code. – Matteo Italia Mar 16 '17 at 13:17
-
@pingaaas - #ifdef macros can make an absolute mess out of your project in the long run. You may instead choose to use a template parameter, and conditionally compile the 'CreateDevice' function using SFINAE. – Jeff Mar 16 '17 at 15:37
0
For more ideas, see answers to this question: Cross-Platform C++ code and single header - multiple implementations
I ended up going with the PIMPL idiom when I faced a similar problem.

user1243123
- 11
- 1