1302 lines
50 KiB
Plaintext
1302 lines
50 KiB
Plaintext
WineLib HOWTO
|
|
Version 28-Dec-2000
|
|
|
|
AUTHOR:
|
|
Wilbur Dale
|
|
Lumin Software BV
|
|
Zandheuvel 52 B
|
|
4901 HW Oosterhout (NB)
|
|
The Netherlands
|
|
|
|
wilbur.dale@lumin.nl
|
|
|
|
WARNING: This HOWTO is incomplete. I expect to add to it on a weekly
|
|
basis until it is complete.
|
|
|
|
=====================================================================
|
|
|
|
Table of Contents
|
|
|
|
I. Introduction: Wine vs. WineLib
|
|
|
|
II. Legal Issues
|
|
|
|
III. How Much Work?
|
|
|
|
IV. File Format Conversion
|
|
|
|
V. Compiling A Simple Win32 Program
|
|
|
|
VI. Compiling A Win32 Program With Resources
|
|
|
|
VII. DLLs
|
|
A. Windows executable and Windows DLL.
|
|
B. Windows executable and WineLib DLL.
|
|
C. WineLib executable and Windows DLL.
|
|
D. WineLib executable and WineLib DLL.
|
|
|
|
VIII. How to use MFC
|
|
A. Using a native MFC DLL
|
|
B. Compiling MFC
|
|
|
|
VIII. Trademarks
|
|
Windows 3.x, Windows 95, Windows 98, Windows NT are trademarks of
|
|
Microsoft Corporation.
|
|
|
|
Unix is a trademark of ???? FIXME: who has the trademark this week?
|
|
|
|
CrypKey is a trademark of Kenonic Controls Ltd.
|
|
|
|
FIXME: Codewright copyright ???
|
|
|
|
All other trademarks are the property of their respective owners.
|
|
|
|
=====================================================================
|
|
|
|
I. Introduction: Wine vs. WineLib
|
|
|
|
WineLib provides the Win32 API to a non-Microsoft operating
|
|
system. The WineLib Win32 functions use X11 functions to perform the
|
|
actual drawing on the screen. Wine and WineLib are based on the same
|
|
set of functions that implement the Win32 API. The difference between
|
|
Wine and WineLib is the type of executable that is loaded into memory
|
|
and executed. If an executable and any associated DLLs were compiled
|
|
for x86 hardware running the Windows 95, 98, or Windows NT (TM)
|
|
operating systems, then Wine can use a special binary loader to load
|
|
the program and the libraries into memory and execute it. WineLib on
|
|
the other hand allows you to take the source for such a program and
|
|
DLLs and compile it into the native format of a x86 Unix or Linux
|
|
operating system. WineLib also allows you to partially compile the
|
|
program and DLLs into the native format. For example, if you use a DLL
|
|
from a vendor to provide some functions to your program and the vendor
|
|
does not give you source, then you can use the Windows version of the
|
|
DLL to provide the functions and compile the rest of your program in
|
|
the native form for your system. [1]
|
|
|
|
Windows compilers and linkers generate executables with a different
|
|
structure than standard compilers. Windows has two executable formats:
|
|
the NE format and the PE format. The NE executable format provides for
|
|
two entry points and the PE format provides for three entry points
|
|
while a standard executable has a single entry point. Usually, a NE or
|
|
a PE executable will use one of the entry points for your program and
|
|
the other entry points will print an error message and exit. However,
|
|
a linker can link 16 bit objects into one or both of the alternate
|
|
entry points of a NE or PE executable.
|
|
|
|
Standard compilers assume that the function main() exists. The entry
|
|
point for a standard program is constructed from the C runtime
|
|
library, initialization code for static variables in your program, the
|
|
initialization code for your classes (C++), and your function main().
|
|
On the other hand, windows compilers assume WinMain() exists. The
|
|
entry point for a windows program is constructed from the C runtime
|
|
library, initialization code for static variables in your program, the
|
|
initialization code for your classes (C++), and your function
|
|
WinMain(). [4]
|
|
|
|
Since main() and WinMain() have different type signatures (parameter
|
|
types), WineLib provides certain aids to generate code so that your
|
|
program can be compiled and run as written for windows. For example,
|
|
WineLib generates a main() to initialize the windows API, to load any
|
|
necessary DLLs and then call your WinMain(). Therefore, you need to
|
|
learn four basic operations to compile a windows program using
|
|
WineLib: compiling a simple program, compiling resources, compiling
|
|
libraries, and compiling MFC (if you will be using MFC). Each of these
|
|
skills or operations are explained in later sections of this HOWTO.
|
|
|
|
Before you start porting your windows code to WineLib, you need to
|
|
consider whether you are allowed to port your program to WineLib. As
|
|
you compile your program using WineLib, you will be combining software
|
|
from several sources and you need to ensure that the licenses for the
|
|
components are compatible. Hence, in the next section, we will examine
|
|
several legal issues.
|
|
|
|
II. Legal Issues
|
|
|
|
Disclaimer! I am not a lawyer. The purpose of this section is to make
|
|
you aware of potential legal problems. Be sure to read your licenses
|
|
and to consult your attorney.
|
|
|
|
During the compilation of your program, you will be combining code
|
|
from several sources: your code, WineLib code, code from your vendor's
|
|
DLLs (if any), and Microsoft MFC code (if used). As a result, you must
|
|
ensure that the licenses of all code sources are obeyed. What you are
|
|
allowed and not allowed to do can vary depending on how you compile
|
|
your program and if you will be distributing it. For example, if you
|
|
are releasing your code under the GPL, you cannot link your code to
|
|
MFC code because the GPL requires that you provide ALL sources to your
|
|
users. The MFC license forbids you from distributing the MFC source so
|
|
you can not comply with the GPL license except by not distributing you
|
|
program. On the other hand, if your code is released under the LGPL,
|
|
you cannot statically link your program to MFC and distribute it, but
|
|
you can dynamically link your LGPL code and MFC code and distribute
|
|
it.
|
|
|
|
Wine/WineLib is distributed under an X11-like license. It places few
|
|
restrictions on the use and distribution of Wine/WineLib code. I doubt
|
|
the Wine license will cause you any problems. On the other hand, MFC
|
|
is distributed under a very restrictive license and the restrictions
|
|
vary from version to version and between service packs.
|
|
|
|
If you plan on using MFC, there are three hurdles to legally using
|
|
MFC. The first hurdle is how to legally get MFC source code on your
|
|
computer. MFC source code comes as a part of Visual Studio. The
|
|
license for Visual Studio implies it is a single product that can not
|
|
be broken up into its components. The cleanest way to get MFC on your
|
|
system is to use a dual boot Linux box with the windows partition
|
|
visible to the Linux OS. Boot into windows and install Visual
|
|
Studio. Since Visual Studio is installed on the computer, you have not
|
|
broken it into its components. There may be other solutions, but I
|
|
think this is the easiest.
|
|
|
|
FIXME: quote relevant sections of EULA in above paragraph.
|
|
|
|
The second hurdle for MFC is the legality of compiling MFC on a
|
|
non-Microsoft operating system. This varies with the version of MFC.
|
|
|
|
MFC license from Visual Studio 6.0:
|
|
|
|
1.1 General License Grant. Microsoft grants to you as an
|
|
individual, a personal, nonexclusive license to make and use
|
|
copies of the SOFTWARE PRODUCT for the sole purposes of designing,
|
|
developing, and testing your software product(s) that are designed
|
|
to operate in conjunction with any Microsoft operating system
|
|
product. [Other unrelated stuff deleted.]
|
|
|
|
So it appears you cannot compile MFC for WineLib using this
|
|
license. On the other hand, Visual Studio 6.0 service pack 3 (Visual
|
|
Studio 5.0 is similar):
|
|
|
|
1.1 General License Grant. Microsoft grants to you as an
|
|
individual, a personal, nonexclusive license to make and use
|
|
copies of the SOFTWARE PRODUCT for the purpose of designing,
|
|
developing, and testing your software product(s). [Other unrelated
|
|
stuff deleted]
|
|
|
|
So it appears you can compile MFC for WineLib using this license.
|
|
|
|
The third hurdle is your legal right to distribute an MFC
|
|
library. Check the relevant section of the license on redistributables
|
|
and your redistribution rights. As I read the license, you only have
|
|
the right to distribute binaries of the MFC library if it has no debug
|
|
information and if you distribute it with an application that provides
|
|
significant added functionality to the MFC library.
|
|
|
|
FIXME: quote relevant sections of EULA in above paragraph.
|
|
|
|
Once you have examined the licenses for all of the sources used in
|
|
compiling your program and have decided you can legally compile you
|
|
program using WineLib, you should probably experiment with your
|
|
program running under Wine to determine how much work will be involved
|
|
in the port. The next section will give advice on estimating the
|
|
amount of work required for porting your program to WineLib.
|
|
|
|
III. How Much Work?
|
|
|
|
Wine and WineLib use the same functions to implement the windows API;
|
|
hence, if your program correctly runs under Wine, it should run under
|
|
WineLib. However, Wine/WineLib is incomplete; you may have trouble
|
|
running your program under Wine. Many people have successfully run many
|
|
programs under Wine, so there is a good chance you will have no
|
|
trouble.
|
|
|
|
Wine executes the binary program that was compiled for a windows
|
|
operating system. There are differences between the windows operating
|
|
system and Unix/Linux operating systems. For example, in Windows 95
|
|
and Windows 98, the program has direct access to the hardware. A copy
|
|
protection program that you purchased for your windows executable may
|
|
use direct hardware access to write data to the disk. Hence, you may
|
|
need to disable the copy protection in order to test your executable
|
|
under Wine.
|
|
|
|
As a specific example, CrypKey is a copy protection program we use at
|
|
Lumin Software. Our program does not execute under Wine with the copy
|
|
protection enabled. We disabled the copy protection, recompiled the
|
|
windows executable, and our program works fine. CrypKey also works for
|
|
Windows NT where it creates a service. Using Wine with the --winver
|
|
nt40 option "almost" gets the our program working with copy
|
|
protection. At a later date, we intend to either implement the system
|
|
calls in Wine that are missing for CrypKey or to use another copy
|
|
protection program that does work under Linux.
|
|
|
|
During the execution of your program, Wine prints error messages to
|
|
standard error. These error messages include "stubs", which are
|
|
windows API functions that have not been completely
|
|
implemented. Depending on the system call, these could be harmless
|
|
or crash your program. Most of the common windows API functions have
|
|
already been implemented, so you should have no missing API functions
|
|
or only a few missing functions. If you intend to continue with the
|
|
port to WineLib, you will need to implement these API
|
|
functions. After running your program for a while, you should have a
|
|
good feel for the number of windows API functions that you need to
|
|
implement.
|
|
|
|
FIXME: give info on Wine command line options to control error
|
|
messages.
|
|
|
|
During the compilation of Wine, you can control the amount of error
|
|
messages and debug information that will be be generated by Wine and
|
|
WineLib. For the version released to your customers, you may want to
|
|
use the following command line to configure the Wine/WineLib
|
|
libraries.
|
|
|
|
./configure --disable-debug --disable-trace
|
|
|
|
The option --disable-debug compiles out all debugging messages and the
|
|
option --disable-trace compile out TRACE messages. [2]
|
|
|
|
It is not necessary for you to implement the entire documented
|
|
behavior of an API function in order to get your program to work. For
|
|
example, many API functions have pointer parameters that are NULL in
|
|
the common cases. If you always call the function with a NULL pointer
|
|
for the default behavior, you can save yourself some effort by
|
|
implementing a function that only works for the NULL pointer
|
|
parameter. If you do this, make sure you test if the parameter is
|
|
non-null and issue a warning for the non-null case. Also document in
|
|
the source that the API function is incomplete.
|
|
|
|
FIXME: give info on the FIXME (macro/function?) for partially
|
|
implemented API functions.
|
|
|
|
Once you have implemented an API function, submit the change back to
|
|
the Wine project so the next person to need the same function does not
|
|
need to repeat your work. Remember, someone else wrote all of the
|
|
other API functions that you are using, so you are benefitting from
|
|
their work. Let other people benefit from your work as well. If you
|
|
work for a company, you may need your company's permission to "give
|
|
away" your work.
|
|
|
|
IV. File Format Conversion
|
|
|
|
Before you can compile your program, you must deal with one major
|
|
difference between Windows and WineLib. Window sources are in DOS
|
|
format with carriage return / line feed at the end of each line of
|
|
text while WineLib files are in Unix format with only line feed at the
|
|
end of each line of text.
|
|
|
|
The main problem with the difference between Unix and DOS format
|
|
source files occurs with macro line continuation. A Unix compiler
|
|
expects a backslash (\) followed by a newline (^J) to indict that a
|
|
macro is continued on the next line. However, a file in DOS format will
|
|
have the characters backslash (\), carriage return (^M), and newline
|
|
(^J). The Unix compiler will interpret the backslash (\), carriage
|
|
return (^M), newline (^) of a file in DOS format as a quoted carriage
|
|
return and newline. The Unix compiler will think the line has ended
|
|
and the macro is completely defined. Hence, before you compile your
|
|
sources, you will need to convert you DOS format sources to Unix
|
|
format. There are several tools such as dos2unix and tr that are
|
|
available to convert the format.
|
|
|
|
FIXME: get more info on dos2unix, tr, and all other such tools and
|
|
give example commands. Until I do [3] is a good source.
|
|
|
|
FIXME: is CR/LF conversion necessary for gcc 2.95 ?
|
|
|
|
V. Compiling A Simple Win32 Program
|
|
|
|
Wine and WineLib are written in C as is the MS Win32 API; thus, if
|
|
have a program that calls only the Win32 API directly, you can compile
|
|
the program using a C compiler and link it with some of the WineLib
|
|
libraries. There are several simple examples of WineLib programs in
|
|
the directory libtest/ in the Wine source tree. We shall examine one
|
|
of these to show you how to compile a WineLib program.
|
|
|
|
The example we shall examine is hello2. If you examine hello2.c, you
|
|
will see it is a windows program that pops up a message box that says
|
|
"Hello, hello!". It can be compiled and run using a windows compiler
|
|
just like any other windows program. However, it can not be compiled
|
|
and run with a non-windows compiler. As mentioned previously, windows
|
|
programs have an entry point called WinMain(), while non-windows
|
|
compilers use an entry point of main(). Hence, we need some "glue" to
|
|
glue the main() entry point to the WinMain() in the windows program.
|
|
|
|
In WineLib, some of the glue is provided by the spec file. Spec files
|
|
are used in several places in Wine and WineLib to provide glue between
|
|
windows code and code for non-windows compilers. WineLib provides a
|
|
tool called winebuild in the tools/winebuild directory that converts a
|
|
spec file into a C file that can be compiled and linked with the
|
|
windows source files. If you examine hello2.spec, you will see the
|
|
following:
|
|
|
|
name hello2
|
|
mode guiexe
|
|
type win32
|
|
|
|
import user32.dll
|
|
import kernel32.dll
|
|
import ntdll.dll
|
|
|
|
Information on the complete format of the spec file can be found in
|
|
<wine>/tools/winebuild/README. Name is the name of the
|
|
application. Mode is the type of "glue" that winebuild needs to
|
|
create. Possible modes are 'dll' for a library, 'cuiexe' for a console
|
|
application, and 'guiexe' for a regular graphical application. Type is
|
|
the type of API, either win32 or win16. Win16 is supported only in
|
|
Wine, not WineLib, so you should use win32. Import is a dll that must
|
|
be loaded for the program to execute.
|
|
|
|
During compilation of the hello2 executable, the following command is
|
|
executed.
|
|
|
|
LD_LIBRARY_PATH="..:$LD_LIBRARY_PATH" \
|
|
../tools/winebuild/winebuild -fPIC -L ../dlls -sym hello2.o \
|
|
-o hello2.spec.c -spec hello2.spec
|
|
|
|
The program winebuild will generate the output file hello2.spec.c (option
|
|
-o hello2.spec.c) from the spec file hello2.spec (option -spec
|
|
hello2.spec). The option -fPIC specifies that winebuild should generate
|
|
position independent code and is only necessary for building shared
|
|
library files (.so files). It is not needed when building the main
|
|
executable spec file, but since there is no assembly code generated
|
|
for the main executable, it doesn't make any difference anyway. [5]
|
|
|
|
The winebuild program is used in several places in Wine as well as
|
|
WineLib; however, only the -spec option will be used in WineLib. The
|
|
output file hello2.spec.c contains the glue code to initialize WineLib
|
|
and call WinMain().
|
|
|
|
In order to run hello2, we will compile the code into a shared library
|
|
(hello2.so) and create a symbolic link (hello2) with the wine
|
|
executable with the following steps.
|
|
|
|
gcc -c -I. -I. -I../include -I../include -g -O2 -Wall -fPIC -DSTRICT \
|
|
-D_REENTRANT -I/usr/X11R6/include -o hello2.o hello2.c
|
|
|
|
to compile the windows program itself and
|
|
|
|
gcc -c -I. -I. -I../include -I../include -g -O2 -Wall -fPIC -DSTRICT \
|
|
-D_REENTRANT -I/usr/X11R6/include -o hello2.spec.o hello2.spec.c
|
|
|
|
to compile the spec file and the glue code. Finally,
|
|
|
|
gcc -shared -Wl,-rpath,/usr/local/lib -Wl,-Bsymbolic -o hello2.so \
|
|
hello2.o hello2.spec.o -L.. -lwine -lncurses -lm -lutil -ldl
|
|
|
|
links the compiled files into a shared library.
|
|
|
|
FIXME: -D_REENTRANT why?
|
|
FIXME: explain compiler options
|
|
FIXME: explain linker options
|
|
|
|
All of the steps are automated with the makefile, so "make hello2.so"
|
|
will execute all of the steps for you. A final step is "make hello2",
|
|
which creates a symbolic link from hello2 to the wine executable. Now,
|
|
when "./hello2" is run, the wine executable sees it was called by the
|
|
name "hello2" and loads the shared library "hello2.so" and executes
|
|
the program.
|
|
|
|
THE INFO BELOW IS OUT OF DATE (28-Dec-2000)
|
|
|
|
Thus, you now have the basics of compiling a simple windows
|
|
program. There are two more things to learn for compiling more complex
|
|
windows programs: windows resources and DLL dependencies. Window
|
|
resources are described in the next section. DLL dependencies are
|
|
handled by linker magic with windows compilers. Thus, in WineLib, you
|
|
will need to provide information about which DLLs your program
|
|
depends. This information is given in the spec file. For example, if
|
|
our hello2 program had a .wav file that it played, it would need the
|
|
multi-media DLL winmm. Our spec file would then be
|
|
|
|
name hello2
|
|
mode guiexe
|
|
type win32
|
|
init WinMain
|
|
import winmm
|
|
|
|
If you need to list multiple DLLs, then the import specification can
|
|
appear multiple times, one line per imported DLL.
|
|
|
|
VI. Compiling A Win32 Program With Resources
|
|
|
|
FIXME: to be continued.
|
|
Describe wrc.
|
|
Go through hello world example 3.
|
|
|
|
VII. DLLs
|
|
|
|
As mentioned in the introduction, Wine allows you to execute windows
|
|
executables and windows libraries under non-Microsoft operating
|
|
systems. WineLib allows you to take sources intended for the windows
|
|
operating system and to compile them to run as native executables
|
|
under a Unix/Linux operating system. With an executable and a single
|
|
library, there are four combinations in which to run the programs and
|
|
the library:
|
|
1. a Windows executable with a Windows DLL,
|
|
2. a Windows executable with WineLib DLL,
|
|
3. a WineLib executable with Windows DLL, and
|
|
4. a WineLib executable with WineLib DLL.
|
|
In this section, we will discuss each of these and discuss the steps
|
|
required to implement the executable/DLL combination.
|
|
|
|
A. Windows executable and Windows DLL
|
|
|
|
Running a windows executable with a windows DLL is not a WineLib
|
|
program: it is a Wine program. If you type
|
|
wine program.exe
|
|
and the DLL is in the search path, then the windows program should run
|
|
using the windows DLL.
|
|
|
|
FIXME: find out what is the search path.
|
|
|
|
B. Windows executable and WineLib DLL
|
|
|
|
Running a windows executable with a WineLib DLL is also accomplished
|
|
using the Wine program. The source code for the DLL is compiled into a
|
|
Unix style shared library. When the windows executable "loads" the
|
|
DLL, Wine will use the shared library (.so file) instead.
|
|
|
|
At first you may wonder why you would want to run a windows executable
|
|
with a WineLib DLL. Such a situation implies you do not have the
|
|
source for the executable, but you do have the source for the
|
|
DLL. This is backwards from what you might expect. However, I do have
|
|
an example where this situation might arise.
|
|
|
|
Codewright is a popular editor in the windows world, and the
|
|
capabilities of Codewright can be extended by using DLLs. Since
|
|
Codewright is a commercial product, you do not have the source and
|
|
must use the windows executable with Wine. If you have written a DLL
|
|
to add functionality to Codewright, you have two choices: you can
|
|
compile the DLL using a windows compiler and use both a windows
|
|
executable and a windows DLL as in case A above, or you can use
|
|
WineLib and compile the DLL as a shared library (.so file). I have no
|
|
idea if Codewright actually runs under Wine, but this is an example of
|
|
why you might decide to use a windows executable and a WineLib
|
|
DLL. Many other editors and other programs use DLLs to extend their
|
|
functionality.
|
|
|
|
In order for Wine to use the WineLib DLL, certain glue code is need to
|
|
replace the linker magic that windows compilers use. As with a simple
|
|
executable, the winebuild program uses a spec file to generate the glue
|
|
code. For example, in the spec file for the DLL will look something like
|
|
name winedll
|
|
type win32
|
|
init winedll_DllMain
|
|
1 cdecl _WINEbirthDay@4 ( str ) WINEbirthDay
|
|
2 cdecl _WINEfullName@4 ( str ) WINEfullName
|
|
The name is the name of the DLL. Since WineLib only supports win32,
|
|
the type should always be win32. The init function is the name of the
|
|
initialization function for the DLL. The initialization function for a
|
|
windows DLL is named DllMain(). You will need to rename the function
|
|
in the DLL source so there will not be any name clashes with the
|
|
DllMain() of other DLLs in you program.
|
|
|
|
The last two lines of the spec file above, provide the export
|
|
information for the DLL. For example, the line
|
|
1 cdecl _WINEbirthDay@4 ( str ) WINEbirthDay
|
|
says that the function at ordinal 1 uses the cdecl calling convention
|
|
for the parameters. The DLL export name is _WINEbirthDay@4. The
|
|
function takes a single parameter that is a string. Finally, the C
|
|
function name to be called whenever this DLL function is called is
|
|
WINEbirthday. You will need a function ordinal line for each function
|
|
in the DLL. The export name and the ordinal can be obtained from the
|
|
windows program dumpbin and the windows version of the DLL. See the
|
|
file <wine>/tools/winebuild/README for more details on the spec file
|
|
format.
|
|
|
|
During the compile process, a command like
|
|
winebuild -fPIC -o winedll.spec.c -spec winedll.spec
|
|
will be executed to create the file winedll.spec.c from information in
|
|
the file winedll.spec. The file winedll.spec.c and winedll.c are
|
|
compiled into object files and used to create the shared library.
|
|
|
|
In order for the program to run, a copy of the shared library must be in
|
|
your EXTRA_LD_LIBRARY_PATH. For example, if your wine.conf file has
|
|
the following line,
|
|
EXTRA_LD_LIBRARY_PATH=${HOME}/wine/lib
|
|
then you must copy the shared library into the directory ~/wine/lib/
|
|
and the shared library will now be in the correct search path.
|
|
|
|
Now when you type
|
|
wine program.exe
|
|
the program will load the shared library (.so).
|
|
|
|
C. WineLib executable and Windows DLL
|
|
|
|
Running a WineLib executable with a Windows DLL is accomplished
|
|
using WineLib. This situation will be common since you may have
|
|
purchased DLLs to use with you project and the DLL vendor may not give
|
|
you the source code for the DLL.
|
|
|
|
In order for WineLib to use the Windows DLL, certain glue code is
|
|
needed to replace the linker magic that windows compilers use. Part of
|
|
the glue code must be written by you. The basic idea of the glue code
|
|
is that you write a new DLL that consists of function pointers. Each
|
|
function in the DLL will consist of a call on a function pointer. For
|
|
example,
|
|
WINEDLL_ConstString WINEDLL_INTERFACE
|
|
WINEfullName( WINEDLL_ConstString handle ) {
|
|
return (* pWINEfullName) ( handle );
|
|
}
|
|
The initialization function for the DLL will use the function
|
|
LoadLibrary() to load the windows DLL and initialize the function
|
|
pointers using the function GetProcAddress().
|
|
|
|
Since Wine can use either windows DLLs or Unix shared libraries (.so),
|
|
the LoadLibrary() function call may have unexpected results if there
|
|
is a winedll.dll and a winedll.so file. Hence, the windows version of
|
|
the DLL should be named something like hiddenWinedll.dll and the
|
|
shared library should be named winedll.so. Now the shared library will
|
|
use LoadLibrary() to load the "hidden" DLL.
|
|
|
|
The shared library will need a spec file. Fortunately, it is simpler
|
|
than case B above. The spec file will look something like
|
|
name winedll
|
|
type win32
|
|
init winedll_DllMain
|
|
The name is the name of the DLL. Since WineLib only supports win32,
|
|
the type should always be win32. The init function is the name of the
|
|
initialization function for the shared library. This is the function
|
|
that will load the "hidden" DLL and initialize the function
|
|
pointers. There is no need for any function ordinals unless your
|
|
program calls functions by the ordinal.
|
|
|
|
During the compile process, a command like
|
|
winebuild -fPIC -o winedll.spec.c -spec winedll.spec
|
|
will be executed to create the file winedll.spec.c from information in
|
|
the file winedll.spec. The file winedll.spec.c and winedll.c are
|
|
compiled into object files and used to create the shared library.
|
|
|
|
Now that the shared library is compiled, you still need to compile
|
|
your program. Part of the compile process for your program will
|
|
consist of a spec file for your program. For example,
|
|
name program
|
|
mode guiexe
|
|
type win32
|
|
init WinMain
|
|
import winedll.dll
|
|
This spec file is similar to the spec file of the simple WineLib
|
|
example in part V above. The only difference is the import
|
|
specification that tells WineLib that the main program uses
|
|
winedll.dll. If this import line is not included, the "hidden" DLL
|
|
will not be loaded and the function pointers will not be initialized.
|
|
|
|
During the compile process, a command like
|
|
winebuild -fPIC -o program.spec.c -spec program.spec
|
|
will be executed to create the file program.spec.c from information in
|
|
the file program.spec. The file program.spec.c and your source code are
|
|
compiled into object files and used to create the executable.
|
|
|
|
D. WineLib executable and WineLib DLL.
|
|
|
|
Running a WineLib executable with a WineLib DLL is accomplished using
|
|
WineLib. The source for the DLL will be combined with a spec file to
|
|
generate the shared library. Likewise, the source for your program and
|
|
a spec file will be combined to create the executable. In the source
|
|
for the DLL, you should change the name of DllMain() to a name like
|
|
winedll_DllMain() so that there will not be a name clash with other
|
|
initialization functions for other DLLs.
|
|
|
|
The shared library's spec file is like case C above. The spec file
|
|
will look something like
|
|
name winedll
|
|
type win32
|
|
init winedll_DllMain
|
|
The init function is the name of the initialization function for the
|
|
shared library (what you renamed DllMain to). There is no need for any
|
|
function ordinals unless your program calls functions by the ordinal.
|
|
|
|
During the compile process, a command like
|
|
winebuild -fPIC -o winedll.spec.c -spec winedll.spec
|
|
will be executed to create the file winedll.spec.c from information in
|
|
the file winedll.spec. The file winedll.spec.c and the source code for
|
|
your DLL are compiled into object files and used to create the shared
|
|
library.
|
|
|
|
Compiling your program is exactly like case C above. For example, the
|
|
spec file for you program will look something like
|
|
name program
|
|
mode guiexe
|
|
type win32
|
|
init WinMain
|
|
import winedll.dll
|
|
|
|
During the compile process, a command like
|
|
winebuild -fPIC -o program.spec.c -spec program.spec
|
|
will be executed to create the file program.spec.c from information in
|
|
the file program.spec. The file program.spec.c and your source code are
|
|
compiled into object files and used to create the executable.
|
|
|
|
VIII. How to use MFC
|
|
A. Using a native MFC DLL
|
|
B. Compiling MFC
|
|
|
|
FIXME: to be continued.
|
|
|
|
=====================================================================
|
|
References
|
|
|
|
Until this HOWTO is complete, I will document who gives me what
|
|
information.
|
|
|
|
Reference [1]
|
|
From: Patrik Stridvall <ps@leissner.se>
|
|
To: "'wilbur.dale@lumin.nl'" <wilbur.dale@lumin.nl>,
|
|
Date: Mon, 5 Jun 2000 14:25:22 +0200
|
|
|
|
First of all WineLib suppport for Win16 has been discontinued
|
|
for quite some time, because:
|
|
|
|
1. It is difficult for us to support and it is impossible
|
|
to do so perfectly without special compiler support,
|
|
because of memory layout issues. For example Win16 int
|
|
is 16-bit and data is aligned 16-bit.
|
|
2. It is in almost all cases easier to port a
|
|
Win16 application to Win32.
|
|
|
|
A minor detail, I personally would prefer that Wine and WineLib
|
|
was always used in the uppercase W and uppercase L variant,
|
|
instead of, as in your document, sometime one variant, sometimes
|
|
another.
|
|
|
|
Reference [2]
|
|
|
|
The exact options for controlling error messages mentioned in the
|
|
reference are apparently incorrect, but may have been correct for some
|
|
earlier version of Wine.
|
|
|
|
From: michael cardenas <mbc@deneba.com>
|
|
To: wilbur.dale@lumin.nl
|
|
Date: Mon, 5 Jun 2000 13:19:34 -0400
|
|
|
|
a few things you should mention...
|
|
|
|
- you can compile resources as a dll under windows and then load the dll
|
|
with wine. That's what we do for canvas. This is probably not ideal, but
|
|
most of my problems porting were in the code. We very seldomly have to
|
|
change the resources for the porting process. But wrc does work for most
|
|
cases...
|
|
|
|
- the error messages can be turned off or turned up with options to
|
|
configure like --enable-trace-msgs=wireoff or --enable-trace-msgs=wireon .
|
|
Take a look at configure.
|
|
|
|
- you probably want to compile your WineLib with --disable-debugger, at
|
|
least for the release version of your app.
|
|
|
|
Reference [3]
|
|
http://fgouget.free.fr/wine/winelib-en.shtml
|
|
|
|
Reference [4]
|
|
Date: Wed, 21 Jun 2000 10:34:10 +0200
|
|
From: Rob Carriere <rob.carriere@lumin.nl>
|
|
To: Wilbur N Dale <wilbur.dale@lumin.nl>
|
|
Subject: WineLib-HOWTO comments
|
|
|
|
Hello Wilbur,
|
|
|
|
Some picking of nits. It reads right well.
|
|
|
|
Some of Windows xyz are registered trade marks, other are vanilla:
|
|
Microsoft: Registered
|
|
Windows NT: Registered
|
|
Windows (95,98): plain
|
|
|
|
A Windows compiler does NOT generate a fake main. Instead, the
|
|
executable file format provides for 2 (NE) or 3 (PE) entry points.
|
|
One of these is your program, the other(s) are normally filled with
|
|
stubs that print an error message and exit. It is possible to instruct
|
|
the _linker_ to link 16-bit objects into one or both of the alternate
|
|
entry points, and create a fat binary.
|
|
|
|
At the C/C++ level, your statement about WinMain() is correct. Of
|
|
course the actual entry point first inits run time lib etc, and then
|
|
calls the C/C++ level entry, but that is also true for main() in the
|
|
standard setup. It may be important to regurgitate this info here,
|
|
though, because some of the fun things that can happen with multiple
|
|
run time libs and DLLs occur at this level.
|
|
|
|
Line 86: I only need to know how compile MFC if I use it... :-)
|
|
|
|
|
|
Best regards,
|
|
Rob mailto:rob.carriere@lumin.nl
|
|
|
|
Reference [5]
|
|
To: wilbur.dale@lumin.nl
|
|
Subject: Re: tool/build questions
|
|
From: Alexandre Julliard <julliard@winehq.com>
|
|
Date: 13 Jun 2000 20:06:23 -0700
|
|
|
|
"Wilbur N. Dale" <wilbur.dale@lumin.nl> writes:
|
|
|
|
> 2. tools/build for WineLib users -- is there ever a need to not specify -pic?
|
|
|
|
-pic is only necessary for building .so files, so it's not needed when
|
|
building the main executable spec file (but since there is no assembly
|
|
code generated for the main exe it doesn't make any difference anyway).
|
|
|
|
--
|
|
Alexandre Julliard
|
|
julliard@winehq.com
|
|
|
|
Reference [6]
|
|
Wine Weekly News #51 (2000 Week 28)
|
|
|
|
Events, progress, and happenings in the Wine community for
|
|
July 10, 2000.
|
|
|
|
Uwe Bonnes and Ove Kaven also reminded of some tools to generate under
|
|
Linux some Windows executables:
|
|
* Cygwin/Mingw: as native Linux apps
|
|
* LCC-Win32: run with the help of Wine
|
|
* Borland C++ 5.5: command line version available for free (after
|
|
registering to Borland users' database)
|
|
|
|
=====================================================================
|
|
|
|
The information included here is from various Wine-devel posting and
|
|
private e-mails. I am including them so that any one starting on MFC
|
|
will have some documentation. Glean what you can and good luck.
|
|
|
|
Before I write more detailed info on compiling MFC I have three
|
|
questions. The info I have mentions three problems:
|
|
|
|
1. Wine header files---what is the status of this? Do changes need
|
|
to be made in the headers and if so, do I submit the changes back
|
|
into Wine cvs? Do the changes need #ifdef for C vs. C++
|
|
compilation?
|
|
|
|
Francois Gouget <fgouget@psn.net> has been doing a lot of work in
|
|
this area. It should be a lot easier to compile using C++ now and to
|
|
compile MFC.
|
|
|
|
2. DOS format files <CR/LF> and no case distinction in
|
|
filenames. Do the extensions Corel made to gcc 2.95 handle this?
|
|
If so, how?
|
|
|
|
3. Microsoft extensions to the C++ syntax. Do the extensions Corel
|
|
made to gcc 2.95 handle this? If so, how?
|
|
|
|
If you have info that needs to be added, send me email at
|
|
<wilbur.dale@lumin.nl> and I will add it.
|
|
|
|
=====================================================================
|
|
|
|
THANKS
|
|
|
|
Most of the information in this file came from postings on
|
|
<Wine-devel@Winehq.com> and from private e-mails. The following people
|
|
contributed information for this document and I thank them for their
|
|
time and effort in answering my questions. I also want to thank them
|
|
for encouraging me to attack the MFC problem.
|
|
|
|
CONTRIBUTERS:
|
|
|
|
Damyan Ognyanoff <Damyan@rocketmail.com>
|
|
Gavriel State <gav@magmacom.com>
|
|
Ian Schmidt <ischmidt@cfl.rr.com>
|
|
Jeremy White <jwhite@codeweavers.com>
|
|
|
|
|
|
From: Ian Schmidt <ischmidt@cfl.rr.com>
|
|
Subject: Re: WineLib and MFC
|
|
|
|
"Wilbur N. Dale" wrote:
|
|
|
|
> What is the status of MFC under WineLib?
|
|
|
|
I don't know precisely. Corel has done more MFC work than anyone (all
|
|
of their applications which they are porting are MFC-based), and
|
|
reportedly they have MFC itself compiled. I was just trying to get a
|
|
moderately simple MFC-using app to compile, with moderate success
|
|
(there are still some problems with MFC's headers after my patch, but
|
|
at least they don't appear to be Wine's fault :) I did not try to
|
|
compile MFC itself.
|
|
|
|
> Which versions of MFC, if any?
|
|
|
|
I have no idea what version Corel uses. As noted in my patch, I was
|
|
fiddling with the headers for MFC 6 (from Visual C++ 6.0 Service Pack
|
|
3). Most of the stuff my patch addressed was for newer IE 5-related
|
|
features, so I'd guess MFC 5 (VC++ 5.0) is likely what they used.
|
|
|
|
> Is there any documentation on how to compile MFC for WineLib? If so
|
|
> where?
|
|
|
|
Not that I know of.
|
|
|
|
> I have started to compile programs using WineLib (hello.c last
|
|
> Sunday) and expect to be ready to start compiling MFC in a couple of
|
|
> weeks. If documentation is not available on compiling MFC, I am
|
|
> willing to write it.
|
|
|
|
Documentation would be a Good Thing, as WineLib in general is grossly
|
|
underdocumented right now. Here's a few tips I discovered to get you
|
|
started:
|
|
|
|
- First off, run all the MFC headers (and source too if you try it)
|
|
through a utility to strip out the DOS carriage returns. They cause
|
|
havoc with GCC when it sees one after a line that ends with a \ (and
|
|
MFC has many macros in it's headers that meet that description). If
|
|
you don't have one, do a Google search on "fromdos" and you should
|
|
locate some source (or it's fairly easy to make your own).
|
|
|
|
- Use GCC 2.95.2, and the -fpermissive flag to make it less picky.
|
|
2.95.2 has some VC++-compatibility features that Corel paid for, and I
|
|
believe more are forthcoming in future GCCs.
|
|
|
|
- Use -I to add whereever you have the MFC headers at to your include
|
|
path, as MFC apps typically use #include <> to access them rather than
|
|
"".
|
|
|
|
- Be prepared to have to rename and/or symlink headers, unless you
|
|
compile on a case-insensitive filesystem :)
|
|
|
|
- When you make install Wine it seems not to include all it's headers
|
|
in /usr/local/include/Wine. To have any chance at getting MFC going
|
|
you'll want to use -I to add the include/ directory from the Wine
|
|
source tarball to the path so it can grab everything.
|
|
|
|
Sorry I can't help you more, but good luck!
|
|
|
|
-Ian Schmidt
|
|
ischmidt@cfl.rr.com
|
|
|
|
|
|
From: Jeremy White <jwhite@codeweavers.com>
|
|
Subject: Re: RFC: Wine 1.0
|
|
|
|
"Wilbur N. Dale" wrote:
|
|
> > Further, we have successfully built MFC after making only
|
|
> > a modest set of changes to it, even with older
|
|
> > versions of g++.
|
|
>
|
|
> Lumin Software is about to use WineLib to port a window program to linux. A
|
|
> couple of years ago we thought we had to make a modification to MFC for one
|
|
> of our projects and we had problems getting MFC to compile under MS Visual C++.
|
|
> After much wailing and gnashing of teeth, we gave up and did things another
|
|
> way. After this bad experience, we were wondering --- approximately how many
|
|
> man-hours did you spend compiling and changing MFC ?
|
|
|
|
Urk. I misspoke. None of the developers here that I thought
|
|
had working versions of MFC with Wine have working versions any
|
|
longer. So, it may be a bit trickier than I led you to believe.
|
|
|
|
We have it working pretty reliably with TWine, but not
|
|
quite so cleanly (yet) with Wine. However, it really shouldn't
|
|
be too difficult, and this is what I can remember of the process:
|
|
|
|
1. If you use a very modern version of gcc (2.95.2 or higher),
|
|
I believe you will need to add the -relaxed flag to
|
|
have any hope of compiling.
|
|
|
|
2. If you use an earlier version of gcc, you will need to
|
|
adjust the many anonymous structs/unions that MFC supplies.
|
|
We prefer this approach, because requiring very
|
|
modern gcc implementations seems harsh to us.
|
|
|
|
3. You will need to adjust for the many type differences
|
|
between MFC intrinsic types and the types supplied by Wine.
|
|
For example, I believe that MFC expects a HANDLE to
|
|
be compatible with certain scalar types, (and it is
|
|
under Windows/VC, but is not with Wine/gcc).
|
|
|
|
4. The key procedure: add many -DNO_XXX flags to the
|
|
makefile. If you start with Microsofts make file
|
|
for MFC, convert it into a Wine makefile, and then turn
|
|
on many of the flags they list there (of the form -DNO_XXX),
|
|
your life will get much easier. Once you get it working
|
|
with a few -DNO_XXX flags, you can go back and add them
|
|
back in.
|
|
|
|
5. The best resource: you need someone who knows C++ very,
|
|
very well. You occassionaly run into very obscure C++
|
|
problems where MS has extended the C++ standard and
|
|
gcc has not. It really helps to have a guru on hand
|
|
when you hit those.
|
|
|
|
|
|
I hope this helps. Sorry for the earlier deceptive post.
|
|
|
|
Jeremy
|
|
|
|
From: Gavriel State <gav@magmacom.com>
|
|
Subject: Re: MFC questions
|
|
|
|
"Wilbur N. Dale" wrote:
|
|
|
|
> 1. Compile MFC. Several years ago we (Lumin Software) tried to
|
|
> compile MFC. The attempt failed and we found another way to do what
|
|
> we wanted. MS documentation states that compiling MFC was
|
|
> deliberately made difficult. Considering my experience with stuff
|
|
> they call "easy" I am not looking forward to compiling MFC. We are
|
|
> currently using Visual Studio 5 for windows development.
|
|
|
|
At Corel, we had MFC compiled and running sample apps in WineLib in
|
|
late 1998. It's mostly a question of the Wine headers, which weren't
|
|
originally up to snuff. We did quite a bit of work on them, and most
|
|
of those changes have been contributed back to WineHQ, so it should be
|
|
pretty easy now. The other thing that was a big deal was getting the
|
|
startup code working properly - since MFC needs to initialize static
|
|
data *after* WineLib gets initialized. I believe that that issue has
|
|
been addressed now on the WineHQ side with some of the work done on
|
|
the .spec file tools recently.
|
|
|
|
-Gav
|
|
|
|
--
|
|
Gavriel State
|
|
CEO
|
|
TransGaming Technologies Inc.
|
|
gav@transgaming.com
|
|
|
|
From: Jeremy White <jwhite@codeweavers.com>
|
|
Subject: Re: MFC questions
|
|
|
|
"Wilbur N. Dale" wrote:
|
|
[snip]
|
|
> 1. Compile MFC. Several years ago we (Lumin Software) tried to
|
|
> compile MFC. The attempt failed and we found another way to do what
|
|
> we wanted. MS documentation states that compiling MFC was
|
|
> deliberately made difficult. Considering my experience with stuff
|
|
> they call "easy" I am not looking forward to compiling MFC. We are
|
|
> currently using Visual Studio 5 for windows development.
|
|
|
|
Wilbur, I personally think that this is the 'right' approach, although
|
|
approach #2 may prove faster.
|
|
|
|
Despite your previous experience, and despite my earlier incorrect
|
|
statements, I think that this is simpler than you fear. It's one of
|
|
those tasks that's darkest before the storm - you spend all of your
|
|
energy getting all the include files to work. Once you have *one*
|
|
object file, the rest go much more quickly (alright, getting it to
|
|
link is also a hairball of a job, but it's tractable <g>).
|
|
|
|
If you're not in a hurry, getting MFC to compile, and having a
|
|
documented procedure for compiling it is on our agenda for the
|
|
relatively near future (see the Wine 1.0 task list).
|
|
|
|
Jer
|
|
|
|
p.s. Stick with Visi C++ 5. IMHO its MFC license is cleaner than that
|
|
of VC 6.
|
|
|
|
From: Gavriel State <gav@magmacom.com>
|
|
Subject: The MSVC++ 6.0 license
|
|
|
|
Jeremy White wrote:
|
|
> p.s. Stick with Visi C++ 5. IMHO its MFC license is cleaner than that
|
|
> of VC 6.
|
|
|
|
Actually, I just picked up a copy of MSVC 6.0 and it appears that they
|
|
changed the license between the original release and the Service Pack
|
|
3 release - they removed the bit in section 1.1 about requiring that
|
|
you be developing your software product only for use with a Microsoft
|
|
OS. In any case, even the original license explicitly says that the
|
|
MFC redistribution rights are *in addition* to the usage rights in
|
|
section 1.1.
|
|
|
|
The relevant portion of the original EULA:
|
|
|
|
1.1 General License Grant. Microsoft grants to you as an individual, a
|
|
personal, nonexclusive license to make and use copies of the SOFTWARE
|
|
PRODUCT for the sole purposes of designing, developing, and testing your
|
|
software product(s) that are designed to operate in conjunction with
|
|
any Microsoft operating system product. [Other unrelated stuff deleted]
|
|
|
|
>From the SP3 EULA:
|
|
|
|
3. Section 1.1 of the EULA is deleted in its entirety and replaced
|
|
with the following:
|
|
|
|
1.1 General License Grant. Microsoft grants to you as an individual, a
|
|
personal, nonexclusive license to make and use copies of the SOFTWARE
|
|
PRODUCT for the purpose of designing, developing, and testing your
|
|
software product(s). [Other unrelated stuff deleted]
|
|
|
|
Disclaimer - I am not a lawyer, but I've spent lots of time with them
|
|
investigating software licenses.
|
|
|
|
-Gav
|
|
|
|
--
|
|
Gavriel State
|
|
CEO
|
|
TransGaming Technologies Inc.
|
|
gav@transgaming.com
|
|
|
|
From: Damyan Ognyanoff <Damyan@rocketmail.com>
|
|
Subject: Need a hint
|
|
|
|
Hi,
|
|
|
|
I manage to build mfc42 as .so library and a application using it (as
|
|
a .so library too). I execute it using simple loader which is linked
|
|
to Wine and I load my application in it's WinMain routine. The
|
|
problem is how clearly to unload mfc and my application (to invoke
|
|
mfc's destructors before loader is terminated) All is fine except that
|
|
there is a "zombi" reference to code in shared library which is
|
|
invoked in Wine code and generate GPF. debugger stops somewhere in
|
|
aplication's InitInstance !!! - and the stack is broken so I can't
|
|
catch where exactly the problem is. Any hints are welcome. I'm using
|
|
Wine-2000517 shapshot downloaded form Wine.datapary.no
|
|
|
|
TNX.
|
|
|
|
Damyan
|
|
p.s.
|
|
If any of You is interested in details I can share my
|
|
experience.
|
|
|
|
WND comment:
|
|
Francois Gouget <fgouget@psn.net> has been doing a lot of work in
|
|
the headers of wine. It should be a lot easier to compile using
|
|
C++ now and to compile MFC. Many of the actions needed in the
|
|
following email are not needed any more.
|
|
|
|
From: Damyan Ognyanoff <Damyan@rocketmail.com>
|
|
Subject: Re: Wine MFC info request
|
|
|
|
hi,
|
|
my MFC is from VC6.0 with SP3
|
|
MFC Bulid: (form afxbld_.h)
|
|
#define _MFC_BUILD 8447
|
|
#define _MFC_USER_BUILD "8447"
|
|
#define _MFC_RBLD 0
|
|
mfcdll.rc
|
|
FILEVERSION 6,0,_MFC_BUILD,_MFC_RBLD
|
|
PRODUCTVERSION 6,0,0,0
|
|
|
|
Hints:
|
|
1. Wine include files
|
|
|
|
In some of them you will find error about '__attribute__' all kinds of
|
|
similar errors can be fixed using proper typedefs first example :
|
|
|
|
typedef BOOL (CALLBACK *DLGPROC)(HWND,UINT,WPARAM,LPARAM);
|
|
|
|
must be converted to
|
|
|
|
typedef BOOL CALLBACK (*DLGPROC)(HWND,UINT,WPARAM,LPARAM);
|
|
|
|
and the second kind is something like
|
|
|
|
TYPE* WINAPI SomeFunction(HWND param1,UINT param2);
|
|
|
|
The problem here is a TYPE* or TYPE& (in some of mfc files) the
|
|
workaround is to declare a type before:
|
|
|
|
typedef TYPE* TYPEPtr;
|
|
|
|
or
|
|
|
|
typedef TYPE& TYPERef;
|
|
|
|
and declaration will look like:
|
|
|
|
TYPEPtr WINAPI SomeFunction(HWND param1,UINT param2);
|
|
|
|
note: don't miss a 'struct' when you define struct type pointers. I
|
|
miss it and get a lot of problems compiling MFC:
|
|
|
|
>>
|
|
struct _TEB;
|
|
typedef !!!struct!!! _TEB* P_TEB;
|
|
extern inline P_TEB WINAPI NtCurrentTeb(void);
|
|
<<
|
|
|
|
Those conversions are semanticaly the same as above but g++ compile
|
|
them and generate proper code to invoke __stdcall kind of functions
|
|
|
|
in some of Wine/obj_XXX.h files: Wine/obj_base.h - there are a lot of
|
|
defines's that are used to declare a COM interfaces
|
|
|
|
#define ICOM_METHOD(ret,xfn) \
|
|
public: virtual ret (CALLBACK xfn)(void) = 0;
|
|
|
|
will be (for all of them that are related to C++ (watch #ifdef's
|
|
carefully)):
|
|
|
|
#define ICOM_METHOD(ret,xfn) \
|
|
public: virtual ret CALLBACK (xfn)(void) = 0;
|
|
|
|
and the second tip is an error when compiler stops on line like:
|
|
|
|
ICOM_DEFINE(ISomeInterfase,IUnknown)
|
|
|
|
watch method declarations above to find something like:
|
|
|
|
ICOM_METHOD1(TYPE*,MethodName, DWORD,dwParam)
|
|
|
|
and replace TYPE* with proper TYPEPtr type. In many cases You will see
|
|
void* which can be replaced simply by LPVOID.
|
|
|
|
qthere are several errors related to anonymous structs and unions but
|
|
they can be avoided with proper - #ifdef __cplusplus
|
|
|
|
This is all about Wine headers I think. If you find something that I
|
|
miss type a line of mail to me.
|
|
|
|
2. MFC
|
|
The rules are the same with some new issues:
|
|
|
|
virtual BOOL Method1(int param1, BOOL (CALLBACK *param2)
|
|
(HWND,UINT,WPARAM,LPARAM));
|
|
|
|
don't compile. I remove a function pointer declaration
|
|
outside method:
|
|
|
|
typedef BOOL CALLBACK
|
|
(*param2Type)(HWND,UINT,WPARAM,LPARAM);
|
|
|
|
virtual BOOL Method1(int param1, param2Type param2);
|
|
|
|
I didn't apply this technique to a operator new
|
|
definitions:
|
|
|
|
void* AFXAPI operator new(size_t nSize);
|
|
|
|
so i remove AFXAPI from these declarations:
|
|
|
|
I got some missed #defines from commctrl.h and I added
|
|
them form VC6.0 include.
|
|
|
|
these are my defines form Makefile which I used to
|
|
compile MFC
|
|
|
|
-DTWINE_NO_CMONIKER \ -- this is related to exclude
|
|
CMonikerFile
|
|
-D__urlmon_h__ \ -- Wine didn't have URL interfaces
|
|
-D_AFX_NO_OLEDB_SUPPORT \
|
|
-D_WIN32 \
|
|
-DNOWIN98 \ -- this is used to exclude all
|
|
unimplemented classes from commctrl
|
|
-D_AFX_PACKING \
|
|
-D_AFX_NO_DHTML_SUPPORT \
|
|
-D_AFX_NO_SOCKET_SUPPORT \
|
|
-D_AFX_NO_SYNC_SUPPORT \
|
|
-D_AFX_NO_OCX_SUPPORT \
|
|
-D_AFX_PORTABLE \
|
|
-D_AFX_OLD_EXCEPTIONS \
|
|
-D_AFX_NO_SOCKET_SUPPORT \
|
|
-D_AFX_NO_DEBUG_CRT \
|
|
-D_AFX_NO_DAO_SUPPORT \
|
|
-D_AFX_NO_OCC_SUPPORT \
|
|
-D_AFX_NO_INET_SUPPORT \
|
|
-D_AFX_NO_RICHEDIT_SUPPORT \
|
|
-D_X86_ \
|
|
-DLONGHANDLES
|
|
|
|
may be you will try to enable some of features of mfc I tested only
|
|
-D_AFX_NO_OCC_SUPPORT but got missing interfaces from Wine
|
|
|
|
in file afxcom_.h
|
|
- _CIP<_Interface, _IID>::~_CIP<_Interface, _IID>()
|
|
+ _CIP<_Interface, _IID>::~_CIP()
|
|
|
|
in file afxtempl.h
|
|
- BOOL Lookup(BASE_CLASS::BASE_ARG_KEY key,
|
|
VALUE& rValue) const
|
|
- { return BASE_CLASS::Lookup(key,
|
|
(BASE_CLASS::BASE_VALUE&)rValue); }
|
|
+ BOOL Lookup(typename BASE_CLASS::BASE_ARG_KEY
|
|
key, VALUE& rValue) const
|
|
+ { return BASE_CLASS::Lookup(key,
|
|
(typename BASE_CLASS::BASE_VALUE&)rValue); }
|
|
|
|
and all releated errors can be fixed in this way.
|
|
|
|
3. spec file
|
|
name mfc42
|
|
type win32
|
|
rsrc mfc42
|
|
|
|
10 stdcall WinMain(long long ptr long) WinMain
|
|
|
|
4. linking
|
|
use -rdynamic wnen link libmfc.so to get ARGV and
|
|
ARGC from loader
|
|
|
|
5. I didn'n build a extension dll with Wine but I suspect that there
|
|
will be some problems related to a chaining Runtime classes form MFC
|
|
to a new dll
|
|
|
|
6. build your app as a MODULE too.
|
|
|
|
7. make a loader and in it's _WinMain:
|
|
... includes are here
|
|
iint PASCAL (*winMain)(HINSTANCE,HINSTANCE,LPSTR,int) =
|
|
0;
|
|
my app uses these to manage filenames
|
|
VOID __cdecl (*_splitpath1)(LPCSTR path, LPSTR drive,
|
|
LPSTR directory, LPSTR filename, LPSTR extension ) =
|
|
NULL;
|
|
VOID __cdecl _splitpath(LPCSTR path, LPSTR drive,
|
|
LPSTR directory, LPSTR filename, LPSTR extension )
|
|
{
|
|
if (_splitpath1)
|
|
_splitpath1(path, drive, directory, filename,
|
|
extension );
|
|
}
|
|
VOID __cdecl (*_makepath1)(LPSTR path, LPCSTR drive,
|
|
LPCSTR directory, LPCSTR filename, LPCSTR extension )
|
|
= NULL;
|
|
VOID __cdecl _makepath(LPSTR path, LPCSTR drive,
|
|
LPCSTR directory, LPCSTR filename, LPCSTR extension )
|
|
{
|
|
if (_makepath1)
|
|
_makepath1(path, drive, directory, filename,
|
|
extension);
|
|
}
|
|
int PASCAL _WinMain(HINSTANCE h,HINSTANCE h1,LPSTR
|
|
lpszCmdParam,int c)
|
|
{
|
|
HINSTANCE hInstance,hins,hlib,htst,hform,himag,hexe;
|
|
int retv;
|
|
|
|
hins = LoadLibrary("CRTDLL.DLL");
|
|
_splitpath1 = GetProcAddress(hins,
|
|
"_splitpath");
|
|
_makepath1 = GetProcAddress(hins,
|
|
"_makepath");
|
|
hins = LoadLibrary("COMCTL32.DLL");
|
|
hins = LoadLibrary("COMDLG32.DLL");
|
|
|
|
|
|
hins = dlopen("libmfc42.so",2);
|
|
hlib = LoadLibrary("mfc42");
|
|
himag = dlopen("libmxformatslib.so",2);
|
|
hform = LoadLibrary("mxformatslib");
|
|
hexe = dlopen("libmxpaint.so",2);
|
|
htst = LoadLibrary("mxpaint");
|
|
|
|
winMain = GetProcAddress(hlib, "WinMain");
|
|
if (winMain)
|
|
{
|
|
retv = winMain (htst, // note the > htst
|
|
< HERE
|
|
0,
|
|
lpszCmdParam,
|
|
SW_NORMAL);
|
|
}
|
|
FreeLibrary(htst);
|
|
FreeLibrary(hform);
|
|
FreeLibrary(hlib);
|
|
dlclose(hexe);
|
|
dlclose(himag);
|
|
dlclose(hins);
|
|
return retv;
|
|
}
|
|
the spec for loader is:
|
|
name c10
|
|
mode guiexe
|
|
type win32
|
|
init _WinMain
|
|
|
|
please find attached a Makefile which i use to build
|
|
MFC
|
|
|
|
Regards
|
|
Damyan.
|
|
|
|
LocalWords: WineLib HOWTO Jul vs DLLs DLL MFC NT FIXME CrypKey Kenonic API TM
|
|
LocalWords: Codewright NE PE WinMain GPL LGPL EULA nonexclusive winver nt dos
|
|
LocalWords: redistributables unix tr CR LF gcc libtest winebuild pic fPIC dll
|
|
LocalWords: guiexe init cuiexe lwine lncurses lm lutil ldl wav winmm wrc lcc
|
|
LocalWords: dllExamples WindowsExeWindowsDLL WindowsExeWineDLL WineExeWineDLL
|
|
LocalWords: WineExeWindowsDLL Borland URL's cd distclean DllMain winemain exe
|
|
LocalWords: winedll cdecl WINEbirthDay str WINEfullName WINEbirthday libtool
|
|
LocalWords: proost conf LD libwinedll Gouget docs dumpbin ConstString Lumin
|
|
LocalWords: pWINEfullName LoadLibrary GetProcAddress hiddenWinedll BV HW dlls
|
|
LocalWords: Zandheuvel Oosterhout linkers executables runtime ntdll sym Wl
|
|
LocalWords: DSTRICT REENTRANT rpath Bsymbolic makefile multi
|