RE: Problem in Win32CORE when building PAR-Packer-0.975 with bleadperl on Win32
Jan Dubois [Wed, 27 Jun 2007 15:34:12 +0000 (08:34 -0700)]
From: "Jan Dubois" <jand@activestate.com>
Message-ID: <02bd01c7b90b$49863720$dc92a560$@com>

Rearranges the initialization of Win32CORE. The Perl interpreter isn't
fully initialized when Perl_init_os_extras() in win32/win32.c is called,
so it is not safe to use the Perl calling mechanism yet. Fixes a problem
building PAR-Packer on Win32.

p4raw-id: //depot/perl@31490

cygwin/cygwin.c
ext/Win32CORE/Win32CORE.c
ext/Win32CORE/Win32CORE.pm
makedef.pl
win32/win32.c

index b774394..2f6e224 100644 (file)
@@ -11,6 +11,7 @@
 #include <process.h>
 #include <sys/cygwin.h>
 #include <alloca.h>
+#include <dlfcn.h>
 
 /*
  * pp_system() implemented via spawn()
@@ -196,17 +197,21 @@ XS(XS_Cygwin_winpid_to_pid)
 void
 init_os_extras(void)
 {
-    char *file = __FILE__;
-    CV *cv;
     dTHX;
+    char *file = __FILE__;
+    void *handle;
 
     newXS("Cwd::cwd", Cygwin_cwd, file);
     newXS("Cygwin::winpid_to_pid", XS_Cygwin_winpid_to_pid, file);
     newXS("Cygwin::pid_to_winpid", XS_Cygwin_pid_to_winpid, file);
 
-    if ((cv = get_cv("Win32CORE::bootstrap", 0))) {
-       dSP;
-       PUSHMARK(SP);
-       (void)call_sv((SV *)cv, G_EVAL|G_DISCARD|G_VOID);
+    /* Initialize Win32CORE if it has been statically linked. */
+    handle = dlopen(NULL, RTLD_LAZY);
+    if (handle) {
+        void (*pfn_init)(pTHX);
+        pfn_init = (void (*)(pTHX))dlsym(handle, "init_Win32CORE");
+        if (pfn_init)
+            pfn_init(aTHX);
+        dlclose(handle);
     }
 }
index a2620b6..7769c74 100644 (file)
@@ -57,10 +57,23 @@ FORWARD(Sleep)
 
 XS(boot_Win32CORE)
 {
-    dXSARGS;
+    /* This function only exists because writemain.SH, lib/ExtUtils/Embed.pm
+     * and win32/buildext.pl will all generate references to it.  The function
+     * should never be called though, as Win32CORE.pm doesn't use DynaLoader.
+     */
+}
+#ifdef __CYGWIN__
+__declspec(dllexport)
+#endif
+void
+init_Win32CORE(pTHX)
+{
+    /* This function is called from init_os_extras().  The Perl interpreter
+     * is not yet fully initialized, so don't do anything fancy in here.
+     */
+
     char *file = __FILE__;
 
-    /* these names are Activeware compatible */
     newXS("Win32::GetCwd", w32_GetCwd, file);
     newXS("Win32::SetCwd", w32_SetCwd, file);
     newXS("Win32::GetNextAvailDrive", w32_GetNextAvailDrive, file);
@@ -82,6 +95,4 @@ XS(boot_Win32CORE)
     newXS("Win32::CopyFile", w32_CopyFile, file);
     newXS("Win32::Sleep", w32_Sleep, file);
     /* newXS("Win32::SetChildShowWindow", w32_SetChildShowWindow, file); */
-
-    XSRETURN_YES;
 }
index dd322fd..0e5d20b 100644 (file)
@@ -1,17 +1,14 @@
 package Win32CORE;
 
-$VERSION = '0.01';
+$VERSION = '0.02';
 
-use strict;
-use warnings;
-use vars qw($VERSION @ISA);
-use base qw(Exporter DynaLoader);
-no warnings "redefine";
-
-bootstrap Win32CORE $VERSION;
+# There is no reason to load this module explicitly.  It will be
+# initialized using xs_init() when the interpreter is constructed.
 
 1;
+
 __END__
+
 =head1 NAME
 
 Win32CORE - Win32 CORE function stubs
index f0e359d..b16a0aa 100644 (file)
@@ -1539,6 +1539,8 @@ foreach my $symbol (@stat_mods)
        try_symbol($symbol);
     }
 
+try_symbol("init_Win32CORE") if $static_ext =~ /\bWin32CORE\b/;
+
 # Now all symbols should be defined because
 # next we are going to output them.
 
index e12ac67..55ab70e 100644 (file)
@@ -4582,15 +4582,17 @@ Perl_init_os_extras(void)
 {
     dTHX;
     char *file = __FILE__;
-    CV *cv;
-    dXSUB_SYS;
 
-    /* load Win32 CORE stubs, assuming Win32CORE was statically linked */
-    if ((cv = get_cv("Win32CORE::bootstrap", 0))) {
-       dSP;
-       PUSHMARK(SP);
-       (void)call_sv((SV *)cv, G_EVAL|G_DISCARD|G_VOID);
-    }
+    /* Initialize Win32CORE if it has been statically linked. */
+    void (*pfn_init)(pTHX);
+#if defined(__BORLANDC__)
+    /* makedef.pl seems to have given up on fixing this issue in the .def file */
+    pfn_init = (void (*)(pTHX))GetProcAddress((HMODULE)w32_perldll_handle, "_init_Win32CORE");
+#else
+    pfn_init = (void (*)(pTHX))GetProcAddress((HMODULE)w32_perldll_handle, "init_Win32CORE");
+#endif
+    if (pfn_init)
+        pfn_init(aTHX);
 
     newXS("Win32::SetChildShowWindow", w32_SetChildShowWindow, file);
 }