Sign in to follow this  
webwraith

Cross platform header file headache

Recommended Posts

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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
#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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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


Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Cross platform doesn't necessarily need such #ifdefs: when using only standard C++, and multiplatform libraries such as SDL, OpenGL, lib ogg, GTK, Qt, wxwidgets, boost, ..., then there's almost no situation possible where you need different code for a different platform because the libraries handle all that for you.

Share this post


Link to post
Share on other sites
True enough on things like SDL and actually rendering with OGL, but each platform has a different set up. In Windows' case (with OpenGL) there are the wglXXXX functions, etc. There's still platform specifics, and I want to be able to just swap DLLs (OK, and change a LoadLibrary() call) to switch between DirectX and OpenGL.

I'm not planning on using a library such as SDL, the purpose of this is to produce my own "engine". Even if that FPS I want to create never sees the light of day...

Share this post


Link to post
Share on other sites
What the original snippet was trying to do, was find out if the code was being compiled on a Windows machine, and to include some typedefs if not. Hence the #ifndef ....

As I said earlier, the _WIN32 is defined in windefs.h, so I figured it was a good candidate to check to see if the end user was running on windows.

Let's put this another way, what's the best (if any) way to work out the OS being compiled on, automatically? Any macros defined for windows, Linux, etc. that are guaranteed to be defined on each system? Or do I have to ask the programmer to define something?

Share this post


Link to post
Share on other sites
Alright, alright, lol, I just wanted to do a few bits, like file handling, sockets, threads, setting up the window, etc. I know I'm not going to make something to rival ID4, just wanted to do a little something to separate the game from the OS. My fault for using the term "Engine", I guess :)

Please ignore my earlier post, I was half asleep when I wrote it. I do want to make a game rather than the engine, and not the other way around

Share this post


Link to post
Share on other sites
Quote:
Original post by webwraith
What the original snippet was trying to do, was find out if the code was being compiled on a Windows machine, and to include some typedefs if not. Hence the #ifndef ....


But that's pointless, because the operating system you're on does not dictate the availability of different types. That is dictated by the compiler you're using.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this