Catch up on stories from the past week (and beyond) at the Slashdot story archive

 



Forgot your password?
typodupeerror
×
Programming IT Technology

Datatypes-Porting Win32 Code to Linux? 10

Dionysus asks: "We have some internal utilities running on Windows NT (using Visual C++) that we would like to port to Linux. The problem is, Microsoft, in its infinite wisdom has extended the language and introduced new types (like CHAR, WCHAR, TCHAR), and new functions (like MultiByteToWideChar()), which makes it impossible to do a straight compile. Note, we are not using WIN32 specific stuff (like MFC, COM etc). Are there any libraries out there that would make the porting easier?"
This discussion has been archived. No new comments can be posted.

Datatypes-Porting Win32 Code to Linux?

Comments Filter:
  • by MSG ( 12810 )
    Have you considered winelib? Part of the Wine project's goal is to be able to re-compile Win32 code on UNIX machines. This produces a native application that does not require the "wine" application to run, just winelib.so (that's actually changing about. the wine guys are separating some stuff into smaller .so's) Try it out, see how it works for you.
  • You may want to read some of this article [xemacs.org].
    It deals a little with the issues of windows treatment of TCHAR, WCHAR.
  • #ifdef wchar_t
    typedef WCHAR wchar_t;
    #else
    # ifdef u_int32_t
    typedef WCHAR u_int32_t;
    # else
    typedef WCHAR unsigned int;
    # endif
    #endif

    typedef CHAR char;

    #ifdef UNICODE
    typedef TCHAR WCHAR;
    #else
    typedef TCHAR char;
    #endif

    #ifdef u_int32_t
    typedef DWORD u_int32_t;
    typedef WORD u_int16_t;
    #else
    /*
    * these are less portable because
    * it assumes 'short' is 16 bit
    * and 'int' is 32 bit
    */
    typedef DWORD unsigned int;
    typedef WORD unsigned short;
    #endif
  • ergh.. maybe I should drink my cup of coffee a bit first before submitting. wchar_t is 32 bit, but WCHAR is 16 bit. #ifdef u_int32_t typedef WCHAR u_int16_t; #else typedef WCHAR unsigned short; #endif
  • for the preprocessor macros, run CL -P from the command line or from VC++: this stops it after the preprocessor step.

    for the typedef'd stuff, steal the type definitions found in winnt.h (i.e. #include "cutdownwinnt.h" somewhere in your source)

    for the Win32 stuff (and yes, calls like ::MultiByteToWideChar() are API functions: this particular one converts ASCII and DBCS strings into Unicode ones), you're going to have to decide whether the functionality's necessary and if so whether any of the GCC libs or add on libs have that functionality or if you're going to have to roll your own. To find out all about those closed secret APIs, look here [microsoft.com].

    HTH
    --
    Cheers

  • Mainwin, at least, as of 6 months ago, was completely useless. Yes, it did successfully emulate the Win32 APIs. Unfortunately, it had about 10 times as many bugs as running natively on these APIs; Many of these bugs could either not be worked around, or were very difficult to work around. The company I was working for was porting their software from Windows to Unix using Mainwin, and eventually got tired of waiting for Yet Another Mainwin Patch to fix these critical bugs that prevented us from shipping. Perhaps Mainwin on Linux is better than Mainwin on Solaris, but... For the price we were paying them, we expected much more than we got. (Part of the price problem, however, is that their code includes parts of the NT source, and as such, they are required to license according to Microsoft terms -- i.e. you have to pay a per-seat runtime license for your software. For every copy of your software that sells, part of that goes to Mainsoft, and in turn, part of that goes to Microsoft.)

    As far as the issue of types goes...

    • CHAR == char
    • WCHAR == wchar_t
    • TCHAR == ( unicode ? wchar_t : char )

    The only real issue with MS types on non-MS compilers are the random MS extensions, which include 'uuid' attributes (for COM integration, basically), and unnamed structs, which many compilers don't support -- i.e. like:

    union { int i; struct { char a; char b; }; };

    In the above example, i and a are both located at offset 0 from the start of the struct, and b is located at offset sizeof(char) from the start of the struct. Normally, you would have to use:

    union { int i; struct { char a; char b; } foo; };

    and access a and b as foo.a and foo.b.

    Not that it's a simple matter to handle the weird MS types, but it's a surmountable issue if you are willing to get into typedefs and some preprocessor ugliness.

  • Put these typedefs in a convenient header file, and it takes care of the types. The Win32 calls are a different matter, but usually you can write your own stubs to get things to compile - implementing them is left as an exercise for the reader!

    Here are my typedefs:

    typedef long int COLORREF;
    typedef long int DWORD;
    typedef long int LONG;
    typedef long int LPARAM;
    typedef int* LPINT;
    typedef char* LPSTR;
    typedef char* LPTSTR;
    typedef const char* LPCSTR;
    typedef const char* LPCTSTR;
    typedef long int LRESULT;
    typedef long int POSITION;
    typedef char TCHAR;
    typedef unsigned int UINT;
    typedef void VOID;
    typedef long int WPARAM;
  • I think you may need to recognize what datatypes have a one-to-one mapping with language standard types, and write an obcenely complex regex to convert them all. (only Perl can handle this easily{Tcl has some hard-core ugliness, haven't tried Python}).

    I've done this a couple times -- it's a little unnerving, but it definitely works quickly. (If you really want to get hard-core, like a having to convert some text in ~10k lines of Perl, try tying directly into the interpreter, to identify scope, quoting, context, fxn calls, etc).

    have fun!
  • The ultimate solution is Mainsoft's MainWin.
    It's not free as Wine but it's the real product.

    http://www.mainsoft.com/

    http://www.mainsoft.com/products/linux/linux_whi te_paper.html

  • It has all the typedefs you should need.

After a number of decimal places, nobody gives a damn.

Working...