397 lines
15 KiB
Plaintext
397 lines
15 KiB
Plaintext
<chapter id="portability-issues">
|
|
<title id="portability-issues.title">Portability issues</title>
|
|
|
|
<sect1 id="anon">
|
|
<title id="anon.title">Anonymous unions/structs</title>
|
|
<para>
|
|
Anonymous structs and unions support depends heavily on the compiler.
|
|
The best support is provided by gcc/g++ 2.96 and later. But these
|
|
versions of gcc come from the development branch so you may want to
|
|
hold off before using them in production. g++ 2.95 supports anonymous
|
|
unions but not anonymous structs and gcc 2.95 supports neither. Older
|
|
versions of gcc/g++ have no support for either.
|
|
since it is anonymous unions that are the most frequent in the
|
|
windows headers, you should at least try to use gcc/g++ 2.95.
|
|
</para>
|
|
<para>
|
|
But you are stuck with a compiler that does not support anonymous
|
|
structs/unions all is not lost. The Wine headers should detect this
|
|
automatically and define <varname>NONAMELESSUNION</varname> /
|
|
<varname>NONAMELESSSTRUCT</varname>. Then any anonymous union will
|
|
be given a name
|
|
<literal>u</literal> or <literal>u2</literal>, <literal>u3</literal>,
|
|
etc. to avoid name clashes. You will then have to modify your code to
|
|
include those names where appropriate.
|
|
</para>
|
|
<para>
|
|
The name that Wine adds to anonymous unions should match that used
|
|
by the Windows headers. So all you have to do to compile your
|
|
modified code in Windows is to explicitly define the
|
|
<varname>NONAMELESSUNION</varname> macro. Note that it would be wise
|
|
to also explicitly define this macro on in your Unix makefile
|
|
(<filename>Makefile.in</filename>) to make sure your code will
|
|
compile even if the compiler does support anonymous unions.
|
|
</para>
|
|
<para>
|
|
Things are not as nice when dealing with anonymous structs.
|
|
Unfortunately the Windows headers make no provisions for compilers
|
|
that do not support anonymous structs. So you will need to be more
|
|
subtle when modifying your code if you still want it to compile in
|
|
Windows. Here's a way to do it:
|
|
</para>
|
|
<programlisting>
|
|
#ifdef WINELIB
|
|
#define ANONS .s
|
|
#else
|
|
#define ANONS
|
|
#endif
|
|
|
|
. . .
|
|
|
|
{
|
|
SYSTEM_INFO si;
|
|
GetSystemInfo(&si);
|
|
printf("Processor architecture=%d\n",si ANONS .wProcessorArchitecture);
|
|
}
|
|
</programlisting>
|
|
<para>
|
|
You may put the <literal>#define</literal> directive directly in the
|
|
source if only few files are impacted. Otherwise it's probably best
|
|
to put it in one of your project's widely used headers.
|
|
Fortunately usage of an anonymous struct is much rarer than usage of
|
|
an anonymous union so these modifications should not be too much work.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 id="unicode">
|
|
<title id="unicode.title">Unicode</title>
|
|
|
|
<para>
|
|
Because gcc and glibc use 4 byte unicode characters, the
|
|
compiler intrinsic <literal>L"foo"</literal> generates unicode
|
|
strings which cannot be used by Winelib (Win32 code expects 16
|
|
bit unicode characters). There are 3 workarounds for this:
|
|
</para>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<para>
|
|
Use the latest gcc version (2.9.7 or later), and pass the
|
|
<parameter>-fshort-wchar</parameter> option to every file
|
|
that is built.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Use the <function>__TEXT("foo")</function> macro, define
|
|
<constant>WINE_UNICODE_REWRITE</constant> for each file
|
|
that is built, and add
|
|
<parameter>-fwritable-strings</parameter> to the compiler
|
|
command line. You should replace all occurrences of
|
|
<type>wchar_t</type> with <type>WCHAR</type> also, since
|
|
<type>wchar_t</type> is the native (32 bit) type. These
|
|
changes allow Wine to modify the native unicode strings
|
|
created by the compiler in place, so that they are 16 bit
|
|
by the time any functions get to use them. This scheme
|
|
works with older versions of gcc (2.95.x+).
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Use the compiler default, but don't call any Win32 unicode
|
|
function without converting the strings first!
|
|
</para>
|
|
</listitem>
|
|
</orderedlist>
|
|
|
|
<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>) as well as Win32 unicode calls
|
|
(API functions ending in W, or having
|
|
<constant>_UNICODE</constant> defined), then you should use
|
|
the msvcrt runtime library instead of glibc. The functions in
|
|
glibc will not work correctly with 16 bit strings.
|
|
</para>
|
|
<para>
|
|
If you need a Unicode string even when
|
|
_<constant>UNICODE</constant> isn't defined, use
|
|
<function>WINE_UNICODE_TEXT("foo")</function>. This will need
|
|
to be wrapped in <function>#ifdef WINELIB</function> to
|
|
prevent breaking your source for windows compiles.
|
|
</para>
|
|
<para>
|
|
To prevent warnings when declaring a single unicode character
|
|
in C, use <function>(WCHAR)L'x'</function>, rather than
|
|
<function>__TEXT('x')</function>. This works on Windows also.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 id="C-library">
|
|
<title id="C-library.title">C library</title>
|
|
|
|
<!-- *** Is all of this covered now? Make sure before deleting ***
|
|
<para>
|
|
Winelib currently only supports on C library: that of your
|
|
compiler. three solutions: native, mixed or msvcrt except we
|
|
only have native right now, using the native C library ->
|
|
different behavior: fopen, O_TEXT, unicode support,
|
|
reimplement msvcrt
|
|
</para>
|
|
-->
|
|
|
|
<para>
|
|
There are 3 choices available to you regarding which C library
|
|
to use:
|
|
</para>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<para>
|
|
Use the glibc native C library.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Use the msvcrt C library.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Use a custom mixture of both.
|
|
</para>
|
|
</listitem>
|
|
</orderedlist>
|
|
|
|
<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. Many of the functions in
|
|
msvcrt are simply resolved to glibc, so in reality options 2
|
|
and 3 are fairly similar choices.
|
|
</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. To do this, add a line:
|
|
</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:
|
|
-->
|