How to abstract your code from platform specific header file - c++

Hi I am trying to find a way to prevent the inclusion of platform specific header file for example windows.h.
Curiously none of the solution I found are not satisfactory to me. Maybe it can't be achieved.
I think to achieve this goal several technique need to be used. And there is a lot of example on internet but I couldn't found any about one aspect. Something has to talk/create to your abstraction. Here is an example:
This is a really simplified version of a render window render target.
//D3D11RenderWindow.h
#include <d3d11.h>
class D3D11RenderWindow: public GfxRenderWindow
{
public:
bool initialize(HWND windowHandle);
private:
HWND windowHandle_; /// Win32 window handle
};
That is not so much the problem, this is a platform specific code that get included only by platform specific code. But we need to actually instanciate this type so an "entry point" need to know about the platform specific code too.
For example a factory class:
//GfxRenderWindowFactory.h
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
class GfxRenderWindow;
class GfxRenderWindowFactory
{
public:
static std::unique_ptr<GfxRenderWindow> make(HWND windowHandle);
};
Now this factory class need to be included by the "client" of the library (here a renderer). What I don't like is that #include "windows.h", because it is too error prone to me, anybody that include it, even if they don't need it will have all the world and windows.... Precompile header is not a solution because now it is enforced by the compiler that all cpp have include it (it is a valuable tool to speed compile time but not a tool to separate platform specific code from the portable code)
What I thought is to put the #include in the cpp before the include of its header instead of in the header file like this:
//GfxRenderWindowFactory.cpp
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#include "GfxRenderWindowFactory.h"
/// Implementation of GfxRenderWindowFactory goed here ....
This way it force anybody that want to use this class to include the relevant platform specific header and they will be in better position to judge if they are including this header in a bad place like in one of their own header file.
What are your solution for this?
What do you think of my solution?, crazy?
I want to point out that to me it is of the uberimportance to do portable code right! Answer like just include windows.h and don't sweat about it is not a valid answer. It is not a good coding practice to me.
I hope i made my question clear. If not tell me i'll clarify
Thanks a lot!
## Edit ##
From a small conversation with hmjd I would like to keep the inclusion of windows.h in the header file since, i agree, this make it way more usable. So it would be nice to have a way to prevent the inclusion in a header file and this way enforce that the file can only be included in a cpp. Is this possible?

Is using a predefined macro, like WIN32, or a macro defined by your build system not sufficient:
#ifdef WIN32
#include <windows.h>
#else
include other platform specific headers
#endif
This is a common approach (and FWIW the only approach I have ever used).

Since the underlying issue is passing an HWND to GfxRenderWindowFactory::make, don't have GfxRenderWindowFactory::make take an HWND.

Hey I worked on the wxsmith cross-platform GUI API. The first thing that you need to do is create classes with your own handles. A handle is 1 of 3 things:
A void *.
Class *.
Struct *.
Use a function like so:
#define create_handle(handle) struct __##handle{unsigned int unused;}; typedef __##handle *##handle;
Then call this function and it creates a struct and a pointer to a struct. The pointer is the handle. Then cast to whatever you desire reinterpret_cast(your handle here); and your done then you can cast like this in your object files or your libs or dlls. And make a global define for your window handle, research how other OS's do it and you done.

Related

Recursion in includes (file 1 includes file 2 that includes file1)

I have been looking around but I have not found any question that really helps me to solve this issue. I am not very experienced, so maybe this problem is trivial and it is a question of my lack of knowledge.
I am trying to solve an issue. Our system has a Logger that takes different logs and puts them into a SharedMemory.
However, from one of our classes (a StateMachine) I can not use the Loogger because of recursion:
Logger.h includes SharedMemory.h
SharedMemory.h includes StateMachine.h
If I include Logger.h in StateMachine.h, compile errors appear everywhere. First i was trying to fix this problem by creating a second SharedMemory that is dedicated exclusively to the Logger and don't include StateMachine.h.
With this approach, the compilation errors were solved, but my manager does not like this design solution.
I have also tried to change include order, and to declare class before the include but it is not working (e.g. declare class SharedMachine; before #include SharedMachine.h)
The includes are like this:
In the StateMachine.h
#ifndef SM_H
#define SM_H
#include <map>
/* (different includes) */
#include Logger.h
In the Logger.h
#include SharedMemory.h
In the SharedMemory.h
#include StateMachine.h
I would like to know if there is any trick that I can use to make the includes work in this way, without architectural changes (that my manager seems not to like).
Try to move includes from header files to source (*.cpp) files
Use forward declarations: What are forward declarations in C++?
Change interfaces to work with pointers or references to needed types instead of using actual types, to make possible using forward declaration (if needed)

How to include WinAPI without contaminating the rest of the code?

I'm working on a library in C++ and a part of it is an abstraction layer of several OS functions that i need. I started implementing that with the Windows API but plan to add support for other platforms with #ifdef and such.
What is however starting to become a problem is that including Windows.h propagates to the whole rest of the code where i don't need it and especially, as it is a library, it will also contaminate the code of other people that would use it. I wouldn't really mind if the Windows API used a namespace or some clear way to distinguish its code but instead they #define a lot of pretty common words such as small, near, far (lowercase) and a lot of the function names are also pretty general.
So i would really like if only the platform specific part of my code had access to these and it wouldn't be included anywhere else. I know that the obvious solution would be to only include Windows.h in the CPP files but that isn't always possible because some of the platform specific data types or structures are class member variables such as:
class Window {
public:
// ...
private:
HWND handle;
};
So is there a way to accomplish this?
Thanks.
Use the pimpl idiom ( http://en.wikipedia.org/wiki/Opaque_pointer ). Limitations of the C++ programming language makes it necessary to use tricks like this in order to get information hiding.
One of the ways of doing that is doing it the same way as you would in C (where you don't have that problem at all, because of the following): Forward-declare a struct in the header file and define its contents in the implementation file.
Most people do that by extracting the entire private part of your example into its own struct, whose contents is only defined in the implementation file, and only put a pointer to it in the header file, as the now only member of the private part of the class.
also, #define WIN32_LEAN_AND_MEAN before the #include in order to strip down what the windows.h gives you.

How can I undeclare DECLARE_HANDLE?

I'm porting a piece of code from VC6 to VS2008. The code typedefs HSPRITE as int. But Windows SDK 6.1 already declared HSPRITE through DECLARE_HANDLE. I don't want to rename HSPRITE in my code since it will consume a lot of time to rename it in .cpp files. So, how can I undeclare HSPRITE?
The only correct way is to not include the header that defines HSPRITE, which may not be an option.
Alternatively you should check out one of the following:
Do you really use HSPRITE as an int? Maybe you can remove the definition of HSPRITE from your code and use the one defined in windows' headers.
Use Find and Replace to rename HSPRITE to some other name in your code; it's a matter of a few seconds.
Best is what #ybungalobill says. If you absolutely cannot use his answer, you can also trick windows.h into not declaring it, like this:
#define HSPRITE DeletedWinapi_HSPRITE// prevent windows.h from defining it
#include <windows.h>
#undef HSPRITE
typedef int HSPRITE;

In C/C++, is there a directive similar to #ifndef for typedefs?

If I want to define a value only if it is not defined, I do something like this :
#ifndef THING
#define THING OTHER_THING
#endif
What if THING is a typedef'd identifier, and not defined? I would like to do something like this:
#ifntypedef thing_type
typedef uint32_t thing_type
#endif
The issue arose because I wanted to check to see if an external library has already defined the boolean type, but I'd be open to hearing a more general solution.
There is no such thing in the language, nor is it needed. Within a single project you should not have the same typedef alias referring to different types ever, as that is a violation of the ODR, and if you are going to create the same alias for the same type then just do it. The language allows you to perform the same typedef as many times as you wish and will usually catch that particular ODR (within the same translation unit):
typedef int myint;
typedef int myint; // OK: myint is still an alias to int
//typedef double myint; // Error: myint already defined as alias to int
If what you are intending to do is implementing a piece of functionality for different types by using a typedef to determine which to use, then you should be looking at templates rather than typedefs.
C++ does not provide any mechanism for code to test presence of typedef, the best you can have is something like this:
#ifndef THING_TYPE_DEFINED
#define THING_TYPE_DEFINED
typedef uint32_t thing_type
#endif
EDIT:
As #David, is correct in his comment, this answers the how? part but importantly misses the why? It can be done in the way above, If you want to do it et all, but important it you probably don't need to do it anyways, #David's answer & comment explains the details, and I think that answers the question correctly.
No there is no such facility in C++ at preprocessing stage. At the max can do is
#ifndef thing_type
#define thing_type uint32_t
#endif
Though this is not a good coding practice and I don't suggest it.
Preprocessor directives (like #define) are crude text replacement tools, which know nothing about the programming language, so they can't act on any language-level definitions.
There are two approaches to making sure a type is only defined once:
Structure the code so that each definition has its place, and there's no need for multiple definitions
#define a preprocessor macro alongside the type, and use #ifndef to check for the macro definition before defining the type.
The first option will generally lead to more maintainable code. The second could cause subtle bugs, if you accidentally end up with different definitions of the type within one program.
As other have already said, there are no such thing, but if you try to create an alias to different type, you'll get a compilation error :
typedef int myInt;
typedef int myInt; // ok, same alias
typedef float myInt; // error
However, there is a thing called ctag for finding where a typedef is defined.
The problem is actually real PITA, because some APIs or SDKs redefine commonly used things. I had issue that header files for a map processing software (GIS) were redefining TRUE and FALSE (generally used by windows SDK)keywords to integer literals instead of true and false keywords ( obviously, that can break SOMETHING). And yes, famous joke "#define true false" is relevant.
define would never feel a typedef or constant declared in C\C++ code because preprocessor doesn't analyze code, it only scans for # statements. And it modifies code prior to giving it to syntax analyzer. SO, in general, it's not possible.
https://msdn.microsoft.com/en-us/library/5xkf423c.aspx?f=255&MSPPError=-2147217396
That one isn't portable so far, though there were known request to implement it in GCC. I think, it also counts as "extension" in MSVC. It's a compiler statement, not a preprocessor statement, so it will not "feel" defined macros, it would detect only typedefs outside of function body. "full type" there means that it will react on full definition, ignoring statements like "class SomeClass;". Use it at own risk.
Edit: apparently it also supported on MacOS now and by Intel comiler with -fms-dialect flag (AIX\Linux?)
This might not directly answer the question, but serve as a possible solution to your problem.
Why not try something like this?
#define DEFAULT_TYPE int // just for argument's sake
#ifndef MY_COOL_TYPE
#define MY_COOL_TYPE DEFAULT_TYPE
#endif
typedef MY_COOL_TYPE My_Cool_Datatype_t;
Then if you want to customize the type, you can either define MY_COOL_TYPE somewhere above this (like in a "configure" header that is included at the top of this header) or pass it as a command line argument when compiling (as far as I know you can do this with GCC and LLVM, maybe others, too).
No there is nothing like what you wanted. I have had your same problem with libraries that include their owntypedefs for things like bool. It gets to be a problem when they just don't care about what you use for bool or if any other libs might be doing the same thing!!
So here's what I do. I edit the header file for the libs that do such things and find the typedef bool and add some code like this:
#ifdef USE_LIBNAME_BOOL
typedef unsigned char bool; // This is the lib's bool implementation
#else
#include <stdbool.h>
#endif
Notice that I included if I didn't want to use the libs' own bool typdef. This means that you need C99 support or later.
As mentioned before this is not included in the C++ standard, but you might be able to use autotools to get the same functionality.
You could use the ac_cxx_bool macro to make sure bool is defined (or different routines for different datatypes).
The solution I ended up using was including stdbool.h. I know this doesn't solve the question of how to check if a typedef is already defined, but it does let me ensure that the boolean type is defined.
This is a good question. C and Unix have a history together, and there are a lot of Unix C typedefs not available on a non-POSIX platform such as Windows (shhh Cygwin people). You'll need to decide how to answer this question whenever you're trying to write C that's portable between these systems (shhhhh Cygwin people).
If cross-platform portability is what you need this for, then knowing the platform-specific preprocessor macro for the compilation target is sometimes helpful. E.g. windows has the _WIN32 preprocessor macro defined - it's 1 whenever the compilation target is 32-bit ARM, 64-bit ARM, x86, or x64. But it's presence also informs us that we're on a Windows machine. This means that e.g. ssize_t won't be available (ssize_t, not size_t). So you might want to do something like:
#ifdef _WIN32
typedef long ssize_t;
#endif
By the way, people in this thread have commented about a similar pattern that is formally called a guard. You see it in header files (i.e. interfaces or ".h" files) a lot to prevent multiple inclusion. You'll hear about header guards.
/// #file poop.h
#ifndef POOP_H
#define POOP_H
void* poop(Poop* arg);
#endif
Now I can include the header file in the implementation file poop.c and some other file like main.c, and I know they will always compile successfully and without multiple inclusion, whether they are compiled together or individually, thanks to the header guards.
Salty seadogs write their header guards programmatically or with C++11 function-like macros. If you like books I recommend Jens Gustedt's "Modern C".
It is not transparent but you can try to compile it one time without typedef (just using the alias), and see if it compiles or not.
There is not such things.
It is possible to desactivate this duplicate_typedef compilator error.
"typedef name has already been declared (with same type)"
On a another hand, for some standardized typedef definition there is often a preprocessor macro defined like __bool_true_false_are_defined for bool that can be used.

A basic understanding of C++ header files

I have a theory question rather than an error report.
I'm a rookie C++ programmer, trying to promote that away
Using the VC++ VS2008 compiler
I am often finding myself wondering WHY I want to take some actions in header files.
For example look at this code block:
#include "DrawScene.h"
#include "Camera.h"
#include "Player.h"
#include "Grid.h"
#include "InputHandler.h"
#include "GameState.h"
class Controller
{
public:
private:
public:
Controller();
~Controller(){}
void Update();
private:
};
And the hooked up CPP file , controller.cpp along with it
#include "stdafx.h"
#include "glut.h"
#include "Controller.h"
#include <iostream>
Grid* grid_ptr = new Grid();
InputHandler* inputHandler_ptr = new InputHandler();
DrawScene* drawScene_ptr = new DrawScene();
GameState* gameState_ptr = new GameState();
Controller::Controller()
{
}
void Controller::Update()
{
}
What is a good way to decide which includes go where? So far I've been going with the " whatever works" method but I find it somewhat unprofessional.
Now even though you can say my code has X syntax errors and design flaws, please do, but the focal point I would appreciate that information remains on the use of .h VS .cpp files.
Why is there even such a design? And what are the pits and traps to always be treading lightly around when making any kind of OOP based C++ program?
What sparked this question for me btw was that I wanted to notify the reader of the header file there will be objects stored in the controller but assigning these uninitialized objects seemed impossible without making them static.
Note: I stem from C# --> C++ , might help to know. That's kind of my perspective on code at this point.
Thank you in advance for you efforts!
EDIT: 26/08/2010 18:16
So the build time is the essence of good includes. Is there more to be cautious about?
This is my personal opinion rather than a consensus best practice, but what I recommend is: in a header file, only include those headers that are necessary to make the contents of the header file compile without syntax errors. And if you can use forward declarations rather than nested inclusions, do so.
The reason for this is, in C++ (unlike C#, iiuc) there's no export control. Everything you include from a header will be visible to the includers of the header, which could be a whole lot of junk that users of your interface should not see.
Generally speaking headers should reside in the cpp file. For standard library includes (and possibly 3rd library includes) you can stick them in headers. However headers defined specifically for your project should go in cpp files whenever possible.
The reason for this is compilation time and dependency issues. Any time you change a header file, the compiler will have to recompile every source file that includes it. When you include a header file in another header file, then the compiler has to recompile every cpp file that includes either header file.
This is why forward declaration and the PIMPL (Pointer to IMPLementation, or opaque pointer) pattern are popular. It allows you to shift at least some of the changes/implementation out of the header file. For example:
// header file:
class SomeType;
class AnotherType
{
private:
SomeType *m_pimpl;
};
doesn't require you to include "sometype.h" whereas:
// header file
class AnotherType
{
private:
SomeType m_impl;
};
does. EDIT: Actually, you don't need to include "sometype.h" in the "anothertype.h" if you ALWAYS include "sometype.h" before "anothertype.h" in EVERY cpp file that includes "anothertype.h".
Sometimes it can be difficult to move a header file to the cpp file. At that point you have a decision - is it better to go through the effort of abstracting the code so you can do so, or is it better to just add the include?
Only include headers in another header if absolutely necessary. If the header can go solely in the source file then that's the best place. You can use forward declarations of classes in the header if you are only using pointers and references to them. Your DrawScene, GameState, Grid and InputHandler classes looks like they might fall into this category.
Note that C++ as a language does not care about the distinction between headers and source files. That's just an extremely common system used by developers to maintain their code. The obvious advantage of using headers is to avoid code duplication and helps, to an extent, to enforce the one-definition-rule for classes, templates and inline functions.
Avoid putting too many (read, any unnecessary) #includes in your .h file. Doing so can lead to long build times, as e.g. whenever you change Camera.h you will have changed Controller.h, so anything that includes Controller.h will need to be rebuilt. Even if it is only a comment that has changed.
Use forward declarations if you are only storing pointer members, then add the #includes to the cpp file.
Theoretically, .h files contain just the interface, and .cpp files, the implementation. However, since private members are arguably implementation, and not interface, this is not strictly true, hence the need for forward declarations in order to minimise unnecessary rebuilds.
It is possible, in C++, to include the whole implementation inline in the class definition, file, much as you might with Java, but this really breaks the .h/.cpp interface/implementation rule.
Header files contain declarations of functions, classes, and other objects, whereas cpp files are meant for implementing these previously declared objects.
Header files exist primarily for historical reasons. It's easier to build a C++ compiler if the definitions of all functions, classes, etc to be used by your code are given before you actually call them.
Usually you use cpp for your implemenation. Implementing functions in header files automatically inlines them, so unless these are very small and / or very frequently called, this is usually not what you want.