Platform independent code?

J

John Smith

I have a visual studio c++ project which is a dynamic dll.
It's made for windows, and has windows.h and other windows specific headers.
I want to compile the same project for linux and for mac os.

Do you have any suggestions how to do that?

I read about some library's like wxwidgets, boost, qt and similar.
Do I have to use one of them?

Thanks in advance.
 
M

Marcel Müller

John said:
I have a visual studio c++ project which is a dynamic dll.
It's made for windows, and has windows.h and other windows specific
headers.
I want to compile the same project for linux and for mac os.

Do you have any suggestions how to do that?

You have to check what kind of interaction the code does with the
Windows API. Remove the include and check the error list.

If it is only for basic services like file system or semaphores it
should be mainly straight forward to do the porting to standard C++ or
Posix compatible code.
But if it is a native C++ GUI application, I would not recommend to
think about porting at all. Write the application anew. Believe me, it
is less work.
Of course, you may copy some of the code that contains the programs
internal logic. But if that code relies on further MS-libraries like MFC
or ATL even this will fail.

Option B: leave the application as it is and start it with wine.

But since you are talking about a shared library I have no idea how you
want to integrate it into a non-windows application. Platform
independent interfaces of shared libraries are extremely rare beyond the
world of platform independent applications like Mozilla or similar.
I read about some library's like wxwidgets, boost, qt and similar.
Do I have to use one of them?

If you want to rewrite the application I would recommend this.


Marcel
 
J

John Smith

You have to check what kind of interaction the code does with the
Windows API. Remove the include and check the error list.

If it is only for basic services like file system or semaphores it
should be mainly straight forward to do the porting to standard C++ or
Posix compatible code.
But if it is a native C++ GUI application, I would not recommend to
think about porting at all. Write the application anew. Believe me, it
is less work.
Of course, you may copy some of the code that contains the programs
internal logic. But if that code relies on further MS-libraries like MFC
or ATL even this will fail.

Option B: leave the application as it is and start it with wine.

But since you are talking about a shared library I have no idea how you
want to integrate it into a non-windows application. Platform
independent interfaces of shared libraries are extremely rare beyond the
world of platform independent applications like Mozilla or similar.


If you want to rewrite the application I would recommend this.


Marcel

Thanks for your help.
Do you know is there a way to use wine just to compile the app?
In that way I could have it statically linked so I don't have to install
anything else (wine) along with my library.

The application is not a gui, it's a dll library. When I remove windows
specific header files, there are a lot of errors about typedefs and some
functions. It's hard to predict how long it would take to rewrite it all.
 
Ö

Öö Tiib

I have a visual studio c++ project which is a dynamic dll.
It's made for windows, and has windows.h and other windows specific headers.
I want to compile the same project for linux and for mac os.

Dynamic libraries are not part of C++. Anything in windows.h is not
part of C++. Making code platform independent is lot of work. For
achieving it it is cheapest to have part of code base different for
different platforms. Have only interface same so you can access them
same way on all platforms.
Do you have any suggestions how to do that?

I read about some library's like wxwidgets, boost, qt and similar.
Do I have to use one of them?

no, but may make your work easier. depends what your "project" does.
 
S

Stuart Golodetz

John said:
I have a visual studio c++ project which is a dynamic dll.
It's made for windows, and has windows.h and other windows specific
headers.
I want to compile the same project for linux and for mac os.

Do you have any suggestions how to do that?

I read about some library's like wxwidgets, boost, qt and similar.
Do I have to use one of them?

Thanks in advance.

If it's of any significant size, I'd rewrite it to be
platform-independent from the ground up - porting a large,
platform-specific project is painful. While you're rewriting it, you can
also improve it - which is generally more motivating than the drudgery
of porting existing code that was never designed for it and fixing ~5000
compiler errors :) You can, of course, reuse chunks of code from the
original where practicable.

From personal experience, I can recommend CMake (www.cmake.org) as a
cross-platform built system - it takes a bit of getting used to, but
will generate platform-specific project files / makefiles for you based
on a script you write.

As others have said, making your code build portably can be a lot of
work up-front. However, I've found that it's then generally pretty easy
to then keep your code portable as you develop. Invest the time (often a
few days, if your project is large) to get your build system set up
right at the beginning, and you'll experience far fewer problems down
the line.

Re. libraries, you don't have to use any of the above. However, I
personally find Boost invaluable, even for platform-specific code. I can
recommend wxWidgets for cross-platform GUI development. Qt is also
well-spoken of by people who've used it - I haven't got personal
experience of it myself, though, so I can't say much about it.

Cheers,
Stu
 
J

John Smith

If it's of any significant size, I'd rewrite it to be
platform-independent from the ground up - porting a large,
platform-specific project is painful. While you're rewriting it, you can
also improve it - which is generally more motivating than the drudgery
of porting existing code that was never designed for it and fixing ~5000
compiler errors :) You can, of course, reuse chunks of code from the
original where practicable.

From personal experience, I can recommend CMake (www.cmake.org) as a
cross-platform built system - it takes a bit of getting used to, but
will generate platform-specific project files / makefiles for you based
on a script you write.

As others have said, making your code build portably can be a lot of
work up-front. However, I've found that it's then generally pretty easy
to then keep your code portable as you develop. Invest the time (often a
few days, if your project is large) to get your build system set up
right at the beginning, and you'll experience far fewer problems down
the line.

Re. libraries, you don't have to use any of the above. However, I
personally find Boost invaluable, even for platform-specific code. I can
recommend wxWidgets for cross-platform GUI development. Qt is also
well-spoken of by people who've used it - I haven't got personal
experience of it myself, though, so I can't say much about it.

Cheers,
Stu

I'm not very experienced in c++. If I decide not to use third party
library's, what do I exactly have to do?
Is it enough just to exclude windows.h and similar windows header files?
Or I'd have to write some directives and include certain files for
linux, windows and mac?
If the letter is the case, I think I'll stick to some third party library.
 
S

Stuart Golodetz

John said:
I'm not very experienced in c++. If I decide not to use third party
library's, what do I exactly have to do?

Depending on what you're trying to do (i.e. if it can't be done using
only the standard library, which happens a lot), you will probably need
to use *some* third-party libraries - but not necessarily the ones you
listed above. The important thing when writing portable code is to find
libraries that support as many platforms as possible (and, in
particular, at least the ones for which you're currently developing or
have plans to develop in the future). Generally speaking, I look for
ones that at least support Windows, Linux and Mac OS.
Is it enough just to exclude windows.h and similar windows header files?

No - everything you use has to work on all the platforms on which you're
building. So you generally can't use any platform-specific libraries
(unless you have equivalents you can substitute in on platforms where
they're not supported, or the functionality they provide is
non-essential). Where you are forced to write platform-specific code,
you have to make sure that it's only compiled on that particular
platform - e.g. by using the preprocessor. If you do end up having to do
that, the general approach is to hide the platform-specific stuff behind
a platform-independent interface.
Or I'd have to write some directives and include certain files for
linux, windows and mac?

You may end up doing that in some cases. For example, I have a portable
header to include relevant OpenGL stuff that contains:

#ifdef _WIN32
#ifndef NOMINMAX
#define NOMINMAX // prevent the min and max macros in windows.h being
defined (they interfere with the Standard C++ equivalents)
#endif
#include <windows.h>
#endif

#include "GLee.h"

#ifndef __APPLE__
#include <GL/gl.h>
#include <GL/glu.h>
#else
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#endif

The key differences there being that:

(a) On Windows, you have to include windows.h before including gl.h.
(b) On Mac, the GL headers are in a directory called OpenGL rather than GL.

There are often lots of annoying little things like this that you need
to play around with to get working.
If the letter is the case, I think I'll stick to some third party library.

Doesn't always help you - see above. Basically, writing portable code is
a bit of a faff (if quite satisfying when you get it working) :)

Incidentally, if you're writing portable code then you'll probably end
up needing to be aware of byte-order and endianness issues, among other
things. Worth a Google...

Cheers,
Stu
 
J

John Smith

Depending on what you're trying to do (i.e. if it can't be done using
only the standard library, which happens a lot), you will probably need
to use *some* third-party libraries - but not necessarily the ones you
listed above. The important thing when writing portable code is to find
libraries that support as many platforms as possible (and, in
particular, at least the ones for which you're currently developing or
have plans to develop in the future). Generally speaking, I look for
ones that at least support Windows, Linux and Mac OS.


No - everything you use has to work on all the platforms on which you're
building. So you generally can't use any platform-specific libraries
(unless you have equivalents you can substitute in on platforms where
they're not supported, or the functionality they provide is
non-essential). Where you are forced to write platform-specific code,
you have to make sure that it's only compiled on that particular
platform - e.g. by using the preprocessor. If you do end up having to do
that, the general approach is to hide the platform-specific stuff behind
a platform-independent interface.


You may end up doing that in some cases. For example, I have a portable
header to include relevant OpenGL stuff that contains:

#ifdef _WIN32
#ifndef NOMINMAX
#define NOMINMAX // prevent the min and max macros in windows.h being
defined (they interfere with the Standard C++ equivalents)
#endif
#include <windows.h>
#endif

#include "GLee.h"

#ifndef __APPLE__
#include <GL/gl.h>
#include <GL/glu.h>
#else
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#endif

The key differences there being that:

(a) On Windows, you have to include windows.h before including gl.h.
(b) On Mac, the GL headers are in a directory called OpenGL rather than GL.

There are often lots of annoying little things like this that you need
to play around with to get working.


Doesn't always help you - see above. Basically, writing portable code is
a bit of a faff (if quite satisfying when you get it working) :)

Incidentally, if you're writing portable code then you'll probably end
up needing to be aware of byte-order and endianness issues, among other
things. Worth a Google...

Cheers,
Stu


It seems that most of the errors are about undeclared identifiers:

BYTE' : undeclared identifier
SYSTEMTIME
HANDLE
TRUE
FALSE
GetLocalTime
wsprintf
WINAPI
....


Maybe I could copy the definitions to a custom header file?
This app is a JNI dll so it's between java and a c api (java app -> JNI
DLL -> C api). There is nothing so specially related to windows here.

I think I could get away with defining these constanst in a custom .h file.

Can I get your opinion?
 
J

John Smith

It seems that most of the errors are about undeclared identifiers:

BYTE' : undeclared identifier
SYSTEMTIME
HANDLE
TRUE
FALSE
GetLocalTime
wsprintf
WINAPI
...


Maybe I could copy the definitions to a custom header file?
This app is a JNI dll so it's between java and a c api (java app -> JNI
DLL -> C api). There is nothing so specially related to windows here.

I think I could get away with defining these constanst in a custom .h file.

Can I get your opinion?

I have a coulpe of platform specific functions for now: LoadLibrary,
GetProcAddress, wsprintf.
I'll try to make some kind of platform specific interface just for them.
I'll let you know the results.
 
S

Stuart Golodetz

John Smith wrote:
It seems that most of the errors are about undeclared identifiers:

BYTE' : undeclared identifier
SYSTEMTIME
HANDLE
TRUE
FALSE
GetLocalTime
wsprintf
WINAPI
....


Maybe I could copy the definitions to a custom header file?
This app is a JNI dll so it's between java and a c api (java app -> JNI
DLL -> C api). There is nothing so specially related to windows here.

I think I could get away with defining these constanst in a custom .h file.

Can I get your opinion?

Sounds like a paramedic's approach to me - "Just keep the code alive
until it can be dealt with properly." (Not convinced that what you're
proposing will work in this case, either -- the things above aren't all
constants, for one thing.) My opinion is that you should rewrite it
properly rather than hacking it :)

Stu
 
J

John Smith

John Smith wrote:


Sounds like a paramedic's approach to me - "Just keep the code alive
until it can be dealt with properly." (Not convinced that what you're
proposing will work in this case, either -- the things above aren't all
constants, for one thing.) My opinion is that you should rewrite it
properly rather than hacking it :)

Stu

You are probably right, but I don't have a lot of time for this :)
I think rewriting everything to have wrappers with platform specific
implementation could take a while.

Maybe it would be easier to use wxwidgets or similar library.
If they have platform independent implementations of functions like
LoadLibrary, GetProcAddress it would speed things up?
 
S

Stuart Golodetz

John said:
You are probably right, but I don't have a lot of time for this :)
I think rewriting everything to have wrappers with platform specific
implementation could take a while.

Maybe it would be easier to use wxwidgets or similar library.
If they have platform independent implementations of functions like
LoadLibrary, GetProcAddress it would speed things up?

wxWidgets is a GUI toolkit - doubt it's what you want. You seem to be
after portable dynamic loading. Different platforms support it in
different ways (unsurprisingly):

http://en.wikipedia.org/wiki/Dynamic_loading

There does seem to be some sort of portable dynamic loading implemented
in GLib - not sure whether it's what you're after, but it was what a
quick Google search turned up, so:

http://library.gnome.org/devel/glib/unstable/glib-Dynamic-Loading-of-Modules.html

You might also take a look at:

http://www.gnu.org/software/libtool/manual/html_node/Using-libltdl.html

Cheers,
Stu
 
J

John Smith

wxWidgets is a GUI toolkit - doubt it's what you want. You seem to be
after portable dynamic loading. Different platforms support it in
different ways (unsurprisingly):

http://en.wikipedia.org/wiki/Dynamic_loading

There does seem to be some sort of portable dynamic loading implemented
in GLib - not sure whether it's what you're after, but it was what a
quick Google search turned up, so:

http://library.gnome.org/devel/glib/unstable/glib-Dynamic-Loading-of-Modules.html


You might also take a look at:

http://www.gnu.org/software/libtool/manual/html_node/Using-libltdl.html

Cheers,
Stu

It seems wxwidgets also have methods for dynamic module loading
(http://docs.wxwidgets.org/2.6.3/wx_wxdynamiclibrary.html#wxdynamiclibrarywxdynamiclibrary).

I'll check that out first.
Maybe it's an overkill to use wxwidgets only for that, but I'll give it
a try.
 
J

Jens Thoms Toerring

You are probably right, but I don't have a lot of time for this :)
I think rewriting everything to have wrappers with platform specific
implementation could take a while.
Maybe it would be easier to use wxwidgets or similar library.
If they have platform independent implementations of functions like
LoadLibrary, GetProcAddress it would speed things up?

While Qt is also a GUI toolkit it comes with a number of classes
that help in writing platform-independent code (at least when the
target platforms are Windows, Linux and Mac OS). E.g. loading dyn-
amic libraries at run-time (and getting at the symbols there-in)
can be dealt with the QLibrary class. For getting the local time
the QTime class could be used.

About the other identifiers you wrote about:

This can probably be replaced by a simple 'unsigned char'
SYSTEMTIME

If this is the structure used e.g. by GetLocalTime() to
return the time then using QT's QTime class instead
could help to solve that problem.

No idea what this is meant for.
TRUE
FALSE

Wouldn't the built-ins 'true' and 'false' do as well?

Perhaps swprintf() could be used as a replacement.

If what I read is correct this has something to do with calling
conventions under Windows. If that's the case simply define it
away for Linux where something like this isn't needed.

Regards, Jens
 
B

BGB / cr88192

John Smith said:
You are probably right, but I don't have a lot of time for this :)
I think rewriting everything to have wrappers with platform specific
implementation could take a while.

Maybe it would be easier to use wxwidgets or similar library.
If they have platform independent implementations of functions like
LoadLibrary, GetProcAddress it would speed things up?

almost never will things for another platform take exactly the same form as
those from the first...

so, if you are just expecting on of these libraries to be a drop-in
replacement that will make their LoadLibrary/... calls work, no, this will
not happen...


for example, Linux provides functions which are analogous to the above
functions. they have different names, different headers, different types,
.... but they do the same basic task.


granted, one could hack it, by providing ones' own implementations of these
functions which redirect to the appropriate API calls when not building on
Windows, but granted, this is an ugly hack...

it is much cleaner and easier not to use Windows specific types/declarations
by default, and to essentially wrap any OS-specific bits, but this is a
little more work on average...
 
B

BGB / cr88192

While Qt is also a GUI toolkit it comes with a number of classes
that help in writing platform-independent code (at least when the
target platforms are Windows, Linux and Mac OS). E.g. loading dyn-
amic libraries at run-time (and getting at the symbols there-in)
can be dealt with the QLibrary class. For getting the local time
the QTime class could be used.

About the other identifiers you wrote about:


This can probably be replaced by a simple 'unsigned char'

typically, I tend to create a typedef for 'byte', which is usually wrapped
in a cruft of defines to deal with the possibility of it already having
already been defined elsewhere.

partial reason though is that I use some stupid code processing tools which
don't fully understand the language syntax, and so would tend to get
confused regarding multi-keyword types.

If this is the structure used e.g. by GetLocalTime() to
return the time then using QT's QTime class instead
could help to solve that problem.

yep, or wrapping it in any number of other ways.

No idea what this is meant for.

typically, it is the base type for a number of other "handle" types, such as
HWND or HICON or similar...

IIRC it is usually a special case of a 'void *' pointer, but will often tend
to point into a special region of memory (in the 3-4GB region on Win32),
rather than to actually directly-addressable memory.
Wouldn't the built-ins 'true' and 'false' do as well?

for C++, yes, but for C (which Windows was also designed to work with) these
don't exist, although it is common to "#define" macros for them in many
apps.

#ifndef __cplusplus
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#ifndef bool
#define bool char
#endif
....
#endif

Windows uses TRUE and FALSE instead.
Perhaps swprintf() could be used as a replacement.

possibly, but functions like this (ie: C99 and newer) don't tend to work in
MSVC (if still working on Windows is a concern).

If what I read is correct this has something to do with calling
conventions under Windows. If that's the case simply define it
away for Linux where something like this isn't needed.

typically, this will work.

I tend to use a macro like:
FOOLIB_API, which contains the needed modifiers (__declspec and friends),
and disappears in cases when not needed (such as when not building on
Windows...).

usually these modifiers may relate both to calling conventions, and as well
managing DLL imports and exports, all of which tend to need to be managed
manually on Windows...


or such...
 
M

Michael Oswald

Maybe it would be easier to use wxwidgets or similar library.
If they have platform independent implementations of functions like
LoadLibrary, GetProcAddress it would speed things up?


You could also try POCO (www.pocoproject.org). It has a lot of portable
abstractions also for dynamic libraries (I created a plugin manager once
with it).

lg,
Michael
 
J

John Smith

While Qt is also a GUI toolkit it comes with a number of classes
that help in writing platform-independent code (at least when the
target platforms are Windows, Linux and Mac OS). E.g. loading dyn-
amic libraries at run-time (and getting at the symbols there-in)
can be dealt with the QLibrary class. For getting the local time
the QTime class could be used.

About the other identifiers you wrote about:


This can probably be replaced by a simple 'unsigned char'

Yes, BYTE shouldn't be a problem.
If this is the structure used e.g. by GetLocalTime() to
return the time then using QT's QTime class instead
could help to solve that problem.

It's returned by GetLocalTime().
No idea what this is meant for.

Not sure about this.
Wouldn't the built-ins 'true' and 'false' do as well?

It's 0 or 1.
Perhaps swprintf() could be used as a replacement.


If what I read is correct this has something to do with calling
conventions under Windows. If that's the case simply define it
away for Linux where something like this isn't needed.

Regards, Jens

I'll consider qt, but I hope I could do this as well with wxwidgets.
The licence suites me better..
 
S

Stuart Golodetz

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top