Okay, I've finally gotten an MFC application to run in a close approximation of what I consider the 'right' way - by having Winelib constructors complete the initialization of Wine, so that the MFC constructors can call Wine APIs. However, I'm not sure if my current approach is the best one, and I was hoping to get some help before hacking some more. Specifically, I have added a special constructor inside libwine.so which initializes most of Wine (by calling PROCESS_InitWine; see my prior patch). Since this constructor fires prior to the MFC constructors, the MFC constructors are able to work. The basic concept, is, IMHO sound. I would like Wine more or less fully functional as soon as libwine.so is done loading. However, this approach has at least two flaws: 1. If we always use this constructor, we are forced to establish our wine server connection without knowing argv (in fact, all constructors have no knowledge of argv, hence no -debugmsg for startup code). 2. GNU ld does not (AFAIK) allow me to specify constructor order. Ideally, I want my new constructor to be the *last* constructor fired. Right now, I've arranged this by jimmying the parameter order passed to the linker, but this could cause problems. I've tried (and prefer) an alternate approach, as follows: 1. Create a new library, say, libwinelib.so, which contains just my constructor. 2. Force all Winelib apps/libs (e.g. MFC) to have libwinelib.so linked in, such that the libwinelib.so ctors/constructors are fired immedately after libwine.so is loaded. This means that all 'normal' Wine invocations will work as before, and only Winelib apps get the special constructor. So, my questions are: 1. Anyone see anything wrong with my basic approaches, or have a better idea for me to try? 2. Question re stupid linker tricks: how would you recommend 'forcing all winelib apps to link in libwinelib.so'. If I add -lwinelib to the link line, it's not in, but if I add /home/jwhite/dlls/libwinelib.so, then my version of GNU ld forces it in. This is pretty distasteful, obviously. The obvious alternative is to create some sort of dummy symbol and then require Winelib apps to depend on that symbol, thereby forcing a link. For example, create WINELIB_Dummy() and require MFC (or all Winelib libraries with constructors) to call WINELIB_Dummy() somewhere. Any thoughts/comments are appreciated. I've attached a patch which contains a libwinelib.so approach, if anyone cares. It does require my patch from earlier tonight. Thanks for listening, Jeremy
Index: configure =================================================================== RCS file: /home/wine/wine/configure,v retrieving revision 1.143 diff -u -r1.143 configure --- configure 2000/07/28 23:04:54 1.143 +++ configure 2000/07/30 03:30:45 @@ -5041,7 +5041,7 @@ #include "confdefs.h" #include <alloca.h> int main() { -void *p = alloca(2 * sizeof(int)); +char *p = alloca(2 * sizeof(int)); ; return 0; } EOF if { (eval echo configure:5048: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then @@ -5506,7 +5506,7 @@ int main() { /* Ultrix mips cc rejects this. */ -typedef int charset[2]; const charset x = {0,0}; +typedef int charset[2]; const charset x; /* SunOS 4.1.1 cc rejects this. */ char const *const *ccp; char **p; @@ -5581,7 +5581,7 @@ #include "confdefs.h" int main() { -} int $ac_kw foo() { +} $ac_kw foo() { ; return 0; } EOF if { (eval echo configure:5588: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then @@ -6391,6 +6391,7 @@ dlls/wow32/Makefile dlls/wsock32/Makefile dlls/x11drv/Makefile +dlls/winelib/Makefile documentation/Makefile documentation/wine.conf.man documentation/wine.man @@ -6627,6 +6628,7 @@ dlls/wow32/Makefile dlls/wsock32/Makefile dlls/x11drv/Makefile +dlls/winelib/Makefile documentation/Makefile documentation/wine.conf.man documentation/wine.man Index: configure.in =================================================================== RCS file: /home/wine/wine/configure.in,v retrieving revision 1.143 diff -u -r1.143 configure.in --- configure.in 2000/07/28 23:04:54 1.143 +++ configure.in 2000/07/30 03:30:46 @@ -1059,6 +1059,7 @@ dlls/wow32/Makefile dlls/wsock32/Makefile dlls/x11drv/Makefile +dlls/winelib/Makefile documentation/Makefile documentation/wine.conf.man documentation/wine.man Index: dlls/Makefile.in =================================================================== RCS file: /home/wine/wine/dlls/Makefile.in,v retrieving revision 1.61 diff -u -r1.61 Makefile.in --- dlls/Makefile.in 2000/07/26 19:51:37 1.61 +++ dlls/Makefile.in 2000/07/30 03:30:47 @@ -71,7 +71,8 @@ winsock/libws2_32.@LIBEXT@ \ winspool/libwinspool.drv.@LIBEXT@ \ wow32/libwow32.@LIBEXT@ \ - wsock32/libwsock32.@LIBEXT@ + wsock32/libwsock32.@LIBEXT@ \ + winelib/libwinelib.@LIBEXT@ # extra names for dlls containing multiple spec files EXTRADLLNAMES = \ @@ -171,6 +172,7 @@ winspool \ wow32 \ wsock32 \ + winelib \ x11drv @MAKE_RULES@ @@ -363,6 +365,9 @@ libwsock32.@LIBEXT@: wsock32/libwsock32.@LIBEXT@ $(RM) $@ && $(LN_S) wsock32/libwsock32.@LIBEXT@ $@ + +libwinelib.@LIBEXT@: winelib/libwinelib.@LIBEXT@ + $(RM) $@ && $(LN_S) winelib/libwinelib.@LIBEXT@ $@ libx11drv.@LIBEXT@: x11drv/libx11drv.@LIBEXT@ $(RM) $@ && $(LN_S) x11drv/libx11drv.@LIBEXT@ $@ =================================================================== --- /dev/null Tue May 5 15:32:27 1998 +++ dlls/winelib/Makefile.in Sat Jul 29 10:20:23 2000 @@ -0,0 +1,13 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = winelib +SOVERSION = 1.0 +IMPORTS = + +C_SRCS = winelib_init.c + +@MAKE_DLL_RULES@ + +### Dependencies: --- /dev/null Tue May 5 15:32:27 1998 +++ dlls/winelib/winelib.spec Sat Jul 29 10:20:35 2000 @@ -0,0 +1,3 @@ +name winelib +type win32 + --- /dev/null Tue May 5 15:32:27 1998 +++ dlls/winelib/winelib_init.c Sat Jul 29 10:33:58 2000 @@ -0,0 +1,55 @@ +/* + * + */ + +#include <assert.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include "windef.h" +#include "wine/winbase16.h" +#include "main.h" +#include "drive.h" +#include "file.h" +#include "options.h" +#include "process.h" +#include "shell.h" +#include "debugtools.h" +#include "server.h" +#include "loadorder.h" + +DEFAULT_DEBUG_CHANNEL(server); + + + +/*---------------------------------------------------------------------- +** Instruct our compiler to create either a constructor or +** an init section which will invoke our library initialization +** code. +** The intended result of this process is that when our .so file +** has finished loading, we can process 'Windows' calls +** in the constructor code of other .so files +** (e.g. mfc) +**--------------------------------------------------------------------*/ + +#ifdef __GNUC__ +static void libinit_init(void) __attribute__((constructor)); +#else /* defined(__GNUC__) */ +static void __asm__dummy_dll_init(void) { +asm("\t.section .init ,\"ax\"\n" + "\tcall libinit_init\n" + "\t.previous\n"); +} +#endif /* defined(__GNUC__) */ + + + +static void libinit_init(void) +{ + PROCESS_InitWine(); +} +