On Thu, Jun 6, 2013 at 10:26 AM, Steve Hay <Steve.Hay@verosoftware.com> wrote: > Ok, so that's actually a perl error about a perl function called > CopyFile(), and I shouldn't have gone off thinking that a C function > missing from the executable was the problem, but I'm still currently at > a loss to see why it isn't working. (It works fine if I use the normal > perl.exe and perl519.dll.) > > Having said that, it seems to be something specific to the module Win32. > Randomly trying a few other XS things (Cwd, Sys::Hostname, Digest::MD5, > Encode) they appear to working fine. > > What is special about Win32 that it doesn't work? Win32 is "special" because many of it's Perl level functions are pre-defined (even without a "use Win32" statement), while the implementation is in a dynamically linked module. This is done via the statically linked Win32CORE wrapper that will load Win32 on demand. The problem here is that Win32CORE is not included in miniperl, so the initialization code has to be called dynamically: In Perl_init_os_extras in win32/win32.c: /* Initialize Win32CORE if it has been statically linked. */ #ifndef PERL_IS_MINIPERL void (*pfn_init)(pTHX); pfn_init = (void (*)(pTHX))GetProcAddress((HMODULE)w32_perldll_handle, "init_Win32CORE"); aTHXa(PERL_GET_THX); if (pfn_init) pfn_init(aTHX); #else The w32_perldll_handle is intialized during DLL_PROCESS_ATTACH in the DllMain() function in win32/perllib.c, which will not be called when perllib.c is part of an .exe file and not in a .dll. So you may want to modify Perl_init_os_extras to something like this: void (*pfn_init)(pTHX); HMODULE module = (HMODULE)((w32_perldll_handle == INVALID_HANDLE_VALUE) ? GetModuleHandle(NULL) : w32_perldll_handle); pfn_init = (void (*)(pTHX))GetProcAddress(module, "init_Win32CORE"); This should be safe even for miniperl, because pfn_init() is only called when it isn't NULL. I notice that DllMain also calls set_w32_module_name(), but I think that may be redundant, because it is called before w32_module_name is used anyways. The only reason I can think of calling it during DllMain would be if perl.exe called set_w32_module_name() before the DLL was loaded, in which case w32_module_name would initially be set to the name of the EXE file, and once the DLL is loaded, it would be reset to the DLL name. In either case, there should be no need to call set_w32_module_name() from Perl_init_os_extras. > It's also still a puzzle to me why the perl-static.exe is only 2MB if it > contains everything necessary from perl519s.lib, which is 20MB. I have no idea... However, 20MB seems rather large to me, so maybe a lot of this is debug information, symbol tables etc. Also, are you sure you are referencing the boot_* symbols of all the submodules as well. E.g. referencing boot_Encode will not pull in the Encode::CN module, which has it's own XS code. So you may need to reference boot_Encode_CN (and JP, KR, TW), which together are about 3MB. There may be other modules which load submodules dynamically, so run a `find . -name *.dll` on a regular Perl on Win32 install and double-check that you have a boot_* reference for all of them. Cheers, -Jan Cheers, -JanThread Previous | Thread Next