Cross platform header file headache

Started by
14 comments, last by Kylotan 16 years, 1 month ago
I'm in the early design stage of writing a cross-platform Engine on which I intend to build an FPS, but I ran into a problem when experimenting with some timing functions, or more specifically, the header;

// platform-specific code
#ifndef _WIN32
typedef unsigned int DWORD;
typedef DWORD UINT;
typedef uint64_t LONGLONG;
#endif

this particular part is giving me problems, in that when I compile the library, the compiler is telling me that it doesn't recognise DWORD,UINT and LONGLONG, telling me, literally, that "LONGLONG/DWORD does not name a type" I'm using the MinGW compiler. If anyone can help me correct this, I would be very grateful
Advertisement
Quote:Original post by webwraith
I'm in the early design stage of writing a cross-platform Engine on which I intend to build an FPS, but I ran into a problem when experimenting with some timing functions, or more specifically, the header;

*** Source Snippet Removed ***

this particular part is giving me problems, in that when I compile the library, the compiler is telling me that it doesn't recognise DWORD,UINT and LONGLONG, telling me, literally, that "LONGLONG/DWORD does not name a type"

I'm using the MinGW compiler. If anyone can help me correct this, I would be very grateful


On MinGW, those types are pulled in via windows.h. What you really want to do is include windows.h on Windows and redefine the types on other OSes.

Actually, if you're looking for cross-platform, an even better solution might be to not use the windows-specific defines like DWORD, UINT, LONGLONG, etc... and try using portable versions like the boost ones. Look in boost/cstdint.hpp.
Is the error actually on those lines, or elsewhere? _WIN32 is likely to be defined for MinGW, since it is, after all, running on WIN32. Thus, those things won't be defined, I expect.

Perhaps you wanted to use _MSC_VER to check for MS Visual Studio, instead?
#ifndef _WIN32 means if _WIN32 is not defined, do the following. If you are compiling this on windows, _WIN32 will be defined, so the compiler will skip those typedefs. What you probably want to do is include <windows.h> if you are on windows:

// platform-specific code#ifndef _WIN32   typedef unsigned int DWORD;   typedef DWORD UINT;   typedef uint64_t LONGLONG;#else   #include <windows.h>#endif


Correct me if I'm missing something.
OK, cheers. I actually got _WIN32 from the windef.h file, as I didn't find anything similar in windows.h (with the exception of _WINDOWS_H :) )

I didn't want to put windows.h in the header to keep the headers completely OS-independent, only including the OS-dependent headers in the source files. I figured this made sense, but please enlighten me if there's a better way
Quote:Original post by webwraith
I didn't want to put windows.h in the header to keep the headers completely OS-independent, only including the OS-dependent headers in the source files. I figured this made sense, but please enlighten me if there's a better way


If there already using windows then it is perfectly fine to include a windows only head.. I would do something like

#ifdef _WIN32      #include "windows.h"#else      ...#endif

Quote:Original post by webwraith
OK, cheers. I actually got _WIN32 from the windef.h file, as I didn't find anything similar in windows.h (with the exception of _WINDOWS_H :) )

I didn't want to put windows.h in the header to keep the headers completely OS-independent, only including the OS-dependent headers in the source files. I figured this made sense, but please enlighten me if there's a better way


There are certain defines you can use to minimize what windows.h brings in, which may be useful. One of these is WIN32_LEAN_AND_MEAN. That can help to minimize things.

My general comment is that windows.h is likely to get pulled in from somewhere, if you're on Windows. It's probably unrealistic (not impossible) to think it can be entirely avoided in headers. If you use the preprocessor to do the right thing on whatever platform you're on, you'll be okay. You can also consider checking other cross platform libraries such as Boost and Qt to see what they do, as it might give you some ideas.
OK, lets try and clear this up a bit. I apologize to anyone who already understood this.


I want to build this system using libraries. The libraries themselves will differ depending on whether the programmer is on Windows, or Linux, or MacOS, etc., however the header files will remain the same. The programmer #includes the headers as normal, but links to the library that is specific to the platform they are running on. This suggests that the header files shouldn't care about what platform they are used on, only the specific library. Therefore, the headers on hold interfaces, while the libraries themselves need to include specifics.

Ugh, that looks like a real mess. Basically, when I come to use my library, I include (say) "mglTime.h", my timer interface, and as I'm developing on Windows, I've linked to the windows version of the timer library. This way, I can swap platforms by changing the libraries I link to.

My problem starts when I need to check for platform-specific types. I think I'm just gonna create a separate "defs.h", which has the required types in it.

@Kylotan: will _MSC_VER work if the end user is using a different compiler? I'm using MinGW, not MSVC.
Quote:Original post by webwraith
OK, lets try and clear this up a bit. I apologize to anyone who already understood this.


I want to build this system using libraries. The libraries themselves will differ depending on whether the programmer is on Windows, or Linux, or MacOS, etc., however the header files will remain the same. The programmer #includes the headers as normal, but links to the library that is specific to the platform they are running on. This suggests that the header files shouldn't care about what platform they are used on, only the specific library. Therefore, the headers on hold interfaces, while the libraries themselves need to include specifics.

Ugh, that looks like a real mess. Basically, when I come to use my library, I include (say) "mglTime.h", my timer interface, and as I'm developing on Windows, I've linked to the windows version of the timer library. This way, I can swap platforms by changing the libraries I link to.

My problem starts when I need to check for platform-specific types. I think I'm just gonna create a separate "defs.h", which has the required types in it.

@Kylotan: will _MSC_VER work if the end user is using a different compiler? I'm using MinGW, not MSVC.


The point is that whatever library you're making, at some point, will need to do something Windows-specific and call Windows APIs at some level, as I'm sure you're aware. I assume there's more than you just needing a few types. Avoiding the inclusion of windows.h from a header is nearly impossible, even for MinGW. So, simply include the windows header if you're on windows and otherwise define the types because they won't otherwise exist.

Like I said, look at a well-established cross platform library, such as Boost. You can get a good idea what a cross platform library does for platform-specific issues (at some level, there are always platform specific issues). For example, Boost has different configurations for different compilers and platforms which result in certain defines. Libraries then use the defines provided by the configurations to include the appropriate libraries and perform the right behavior.
OK, suitably chastened, I'm off to look up Boost.

This topic is closed to new replies.

Advertisement