| <chapter id="portability-issues"> |
| <title id="portability-issues.title">Portability issues</title> |
| |
| <sect1 id="unicode"> |
| <title id="unicode.title">Unicode</title> |
| |
| <para> |
| The <literal>wchar_t</literal> type has different standard |
| sizes in Unix (4 bytes) and Windows (2 bytes). You need a |
| recent gcc version (2.9.7 or later) that supports the |
| <parameter>-fshort-wchar</parameter> option to set the |
| size of <literal>wchar_t</literal> to the one expected |
| by Windows applications. |
| </para> |
| |
| <para> |
| If you are using Unicode and you want to be able to use |
| standard library calls (e.g. <function>wcslen</function>, |
| <function>wsprintf</function>), then you must use |
| the msvcrt runtime library instead of glibc. The functions in |
| glibc will not work correctly with 16 bit strings. |
| </para> |
| </sect1> |
| |
| <sect1 id="C-library"> |
| <title id="C-library.title">C library</title> |
| |
| <para> |
| There are 2 choices available to you regarding which C library |
| to use: the native glibc C library or the msvcrt C library. |
| </para> |
| |
| <para> |
| Note that under Wine, the crtdll library is implemented using |
| msvcrt, so there is no benefit in trying to use it. |
| </para> |
| <para> |
| Using glibc in general has the lowest overhead, but this is |
| really only important for file I/O, as many of the functions |
| in msvcrt are simply resolved to glibc. |
| </para> |
| <para> |
| To use glibc, you don't need to make changes to your |
| application; it should work straight away. There are a few |
| situations in which using glibc is not possible: |
| </para> |
| <orderedlist> |
| <listitem> |
| <para> |
| Your application uses Win32 and C library unicode |
| functions. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| Your application uses MS specific calls like |
| <function>beginthread()</function>, |
| <function>loadlibrary()</function>, etc. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| You rely on the precise semantics of the calls, for |
| example, returning <literal>-1</literal> rather than |
| non-zero. More likely, your application will rely on calls |
| like <function>fopen()</function> taking a Windows path |
| rather than a Unix one. |
| </para> |
| </listitem> |
| </orderedlist> |
| <para> |
| In these cases you should use msvcrt to provide your C runtime |
| calls. |
| </para> |
| |
| <programlisting>import msvcrt.dll</programlisting> |
| |
| <para> |
| to your applications <filename>.spec</filename> file. This |
| will cause <command>winebuild</command> to resolve your c |
| library calls to <filename>msvcrt.dll</filename>. Many simple |
| calls which behave the same have been specified as |
| non-importable from msvcrt; in these cases |
| <command>winebuild</command> will not resolve them and the |
| standard linker <command>ld</command> will link to the glibc |
| version instead. |
| </para> |
| <para> |
| In order to avoid warnings in C (and potential errors in C++) |
| from not having prototypes, you may need to use a set of MS |
| compatible header files. These are scheduled for inclusion |
| into Wine but at the time of writing are not available. Until |
| they are, you can try prototyping the functions you need, or |
| just live with the warnings. |
| </para> |
| <para> |
| If you have a set of include files (or when they are available |
| in Wine), you need to use the <parameter>-isystem |
| "include_path"</parameter> flag to gcc to tell it to use your |
| headers in preference to the local system headers. |
| </para> |
| <para> |
| To use option 3, add the names of any symbols that you don't |
| want to use from msvcrt into your applications |
| <filename>.spec</filename> file. For example, if you wanted |
| the MS specific functions, but not file I/O, you could have a |
| list like: |
| </para> |
| |
| <programlisting>@ignore = ( fopen fclose fwrite fread fputs fgets )</programlisting> |
| <para> |
| Obviously, the complete list would be much longer. Remember |
| too that some functions are implemented with an underscore in |
| their name and <function>#define</function>d to that name in |
| the MS headers. So you may need to find out the name by |
| examining <filename>dlls/msvcrt/msvcrt.spec</filename> to get |
| the correct name for your <function>@ignore</function> entry. |
| </para> |
| </sect1> |
| |
| <sect1 id="porting-compiling"> |
| <title id="porting-compiling.title">Compiling Problems</title> |
| <para> |
| If you get undefined references to Win32 API calls when |
| building your application: if you have a VC++ |
| <filename>.dsp</filename> file, check it for all the |
| <filename>.lib</filename> files it imports, and add them to |
| your applications <filename>.spec</filename> |
| file. <command>winebuild</command> gives you a warning for |
| unused imports so you can delete the ones you don't need |
| later. Failing that, just import all the DLL's you can find in |
| the <filename>dlls/</filename> directory of the Wine source |
| tree. |
| </para> |
| <para> |
| If you are missing GUIDs at the link stage, add |
| <parameter>-lwine_uuid</parameter> to the link line. |
| </para> |
| <para> |
| gcc is more strict than VC++, especially when compiling |
| C++. This may require you to add casts to your C++ to prevent |
| overloading ambiguities between similar types (such as two |
| overloads that take int and char respectively). |
| </para> |
| <para> |
| If you come across a difference between the Windows headers |
| and Wine's that breaks compilation, try asking for help on |
| <email>wine-devel@winehq.com</email>. |
| </para> |
| </sect1> |
| |
| <sect1 id="init-problems"> |
| <title id="init-problems.title">Initialization problems</title> |
| <para> |
| Initialization problems occur when the application calls the Win32 API |
| before Winelib has been initialized. How can this happen? |
| </para> |
| <para> |
| Winelib is initialized by the application's <function>main</function> |
| before it calls the regular <function>WinMain</function>. But, in C++, |
| the constructors of static class variables are called before the |
| <function>main</function> (by the module's initializer). So if such |
| a constructor makes calls to the Win32 API, Winelib will not be |
| initialized at the time of the call and you may get a crash. This |
| problem is much more frequent in C++ because of these class |
| constructors but could also, at least in theory, happen in C if you |
| were to specify an initializer making calls to Winelib. But of |
| course, now that you are aware of this problem you won't do it :-). |
| </para> |
| <para> |
| Further compounding the problem is the fact that Linux's (GNU's?) |
| current dynamic library loader does not call the module |
| initializers in their dependency order. So even if Winelib were to |
| have its own initializer there would be no guarantee that it would be |
| called before the initializer of the library containing this static |
| variable. Finally even if the variable is in a library that your |
| application links with, that library's initializer may be called |
| before Winelib has been initialized. One such library is the MFC. |
| </para> |
| <para> |
| The current workaround is to move all the application's code in a |
| library and to use a small Winelib application to dynamically load |
| this library. Tus the initialization sequence becomes: |
| </para> |
| <itemizedlist> |
| <listitem> |
| <para> |
| the wrapper application starts. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| its empty initializer is run. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| its <function>main</function> is run. Its first task is to |
| initialize Winelib. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| it then loads the application's main library, plus all its |
| dependent libraries. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| which triggers the execution of all these libraries initializers |
| in some unknown order. But all is fine because Winelib has |
| already been initialized anyway. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| finally the main function calls the <function>WinMain</function> |
| of the application's library. |
| </para> |
| </listitem> |
| </itemizedlist> |
| <para> |
| This may sound complex but Winemaker makes it simple. Just specify |
| <option>--wrap</option> or <option>--mfc</option> on the command line |
| and it will adapt its makefiles to build the wrapper and the |
| application library. |
| </para> |
| </sect1> |
| |
| <sect1 id="com-support"> |
| <title id="com-support.title">VC's native COM support</title> |
| <para> |
| don't use it, |
| guide on how to replace it with normal C++ code (yes, how???): |
| extracting a .h and .lib from a COM DLL |
| Can '-fno-rtti' be of some use or even required? |
| </para> |
| </sect1> |
| |
| <sect1 id="SEH"> |
| <title id="SEH.title">SEH</title> |
| <para> |
| how to modify the syntax so that it works both with gcc's macros and Wine's macros, |
| is it even possible? |
| </para> |
| </sect1> |
| |
| <sect1 id="others"> |
| <title id="others.title">Others</title> |
| <para> |
| -fpermissive and -fno-for-scope, |
| maybe other options |
| </para> |
| </sect1> |
| </chapter> |
| |
| <!-- Keep this comment at the end of the file |
| Local variables: |
| mode: sgml |
| sgml-parent-document:("winelib-user.sgml" "book" "chapter" "") |
| End: |
| --> |