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();
+}
+

Reply via email to