Perl-Dist-Strawberry icon indicating copy to clipboard operation
Perl-Dist-Strawberry copied to clipboard

loadable library and perl binaries are mismatched on 5.40+

Open alanoflanagan opened this issue 5 months ago • 17 comments

While building and loading a simple XS module using Strawberry Perl 5.40.2.1 and gmake, we encountered the following runtime error:

loadable library and perl binaries are mismatched
(got first handshake key 0000000012d00080, needed 0000000012c00080)

Details:

We are using both perl.exe and libperl540.a directly from the Strawberry Perl 5.40.2.1 installation.

The XS module is built using standard ExtUtils::MakeMaker tooling and compiled with gmake on Windows.

The build links against the following library:

C:\strawberry-perl-5.40.2.1\perl\lib\CORE\libperl540.a Despite this, the resulting .dll fails to load due to a binary handshake mismatch with the interpreter.

Conclusion:

It seems the libperl540.a provided in the Strawberry Perl 5.40.2.1 distribution is not correctly aligned with the shipped perl.exe and perl540.dll. This prevents successful dynamic linking for XS modules, even when using only Strawberry Perl’s own toolchain.

We're happy to provide a minimal reproducible test case if needed. perlxs_test.zip

/c/strawberry-perl-5.38.4.1/perl/bin/perl.exe Makefile.PL
gmake
/c/strawberry-perl-5.38.4.1/perl/bin/perl.exe  -Mblib -MSimple -e "print Simple::add(2, 3), '\n';"

Code Fails with 5.40.2.1 and 5.40.2.2 but works 5.38.4.1 Best regards, Alan O Flanagan

alanoflanagan avatar Jul 16 '25 10:07 alanoflanagan

The distro builds fine for me using perl-5.40.2.1, and your one-liner test produces expected output:

>perl -Mblib -MSimple -e "print Simple::add(2, 3), '\n';"
5\n
>

BTW, you probably meant something like:

D:\s\perl_xs\perlxs_test>perl -Mblib -MSimple -e "print Simple::add(2, 3), \"\n\";"
5

>

I think your problem probably arises beause your SP-5.40.2.1 is finding some files that are part of another build of perl - perhaps 5.38.4.1 ?

Are you installing Strawberry Perl from the .msi package or the .zip package ? If you've installed from the .msi packages, then it can get a bit tricky if you want to have more than one version of perl installed.

sisyphus avatar Jul 16 '25 11:07 sisyphus

Yeah that 5\n was the same output i was seeing in the 5.38v. I am using strawberry-perl-5.40.2.1-64bit-portable.zip but am building msys2 mingw64 env. This has a system perl which is 5.38.2 version. I have renamed that exe so it is no longer visible. I don't want the system perl to be used. And all the paths look correct below.

 /c/strawberry-perl-5.40.2.1/perl/bin/perl.exe Makefile.PL;gmake;
/c/strawberry-perl-5.40.2.1/perl/bin/perl.exe  -Mblib -MSimple -e "print Simple::add(2, 3), '\n';";
Generating a gmake-style Makefile
Writing Makefile for Simple
Writing MYMETA.yml and MYMETA.json
Skip blib\lib\Simple.pm (unchanged)
Running Mkbootstrap for Simple ()
"C:\strawberry-perl-5.40.2.1\perl\bin\perl.exe" -MExtUtils::Command -e chmod -- 644 "Simple.bs"
"C:\strawberry-perl-5.40.2.1\perl\bin\perl.exe" -MExtUtils::Command::MM -e cp_nonempty -- Simple.bs blib\arch\auto\Simple\Simple.bs 644
gcc -c   -std=c99 -DWIN32 -DWIN64 -DPERL_TEXTMODE_SCRIPTS -DMULTIPLICITY -DPERL_IMPLICIT_SYS -DUSE_PERLIO -D__USE_MINGW_ANSI_STDIO -fwrapv -fno-strict-aliasing -mms-bitfields -O2   -DVERSION=\"0.01\" -DXS_VERSION=\"0.01\"  "-IC:\strawberry-perl-5.40.2.1\perl\lib\CORE"   Simple.c
g++.exe Simple.def -o blib\arch\auto\Simple\Simple.xs.dll -mdll -s -L"C:\strawberry-perl-5.40.2.1\perl\lib\CORE" -L"C:\strawberry-perl-5.40.2.1\c\lib" Simple.o   "C:\strawberry-perl-5.40.2.1\perl\lib\CORE\libperl540.a" -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32 -Wl,--enable-auto-image-base
"C:\strawberry-perl-5.40.2.1\perl\bin\perl.exe" -MExtUtils::Command -e chmod -- 755 blib\arch\auto\Simple\Simple.xs.dll
Simple.c: loadable library and perl binaries are mismatched (got first handshake key 0000000012d00080, needed 0000000012c00080)

alanoflanagan avatar Jul 16 '25 11:07 alanoflanagan

But, for example, which "gcc.exe" and "g++.exe" are being called ? Are they the ones that ship with Strawberry Perl, or are they from within the msys2 installation ? It will be the ones that occur first in the PATH. (I'm not saying that's the precise problem, but your Strawberry Perl is finding and pulling in something from outside of the files that it shipped with.) Can you give us the contents of the PATH environment variable? (In cmd.exe shell that would be set PATH, but probably echo $PATH in the MSYS2 shell.)

sisyphus avatar Jul 16 '25 14:07 sisyphus

Running under an MSYS2 shell can introduce a range of potential clashes. At the least you need to ensure the path has the .../c/bin, .../perl/bin and .../perl/site/bin dirs in it, probably at the start so Strawberry Perl will get all of its utilities and DLLs before seeing anything from MSYS2.

These are set in the portableshell.bat at the top of the portable distributions so you could always start a portable shell from MSYS2, do what you need, and then exit. These can also be called with arguments, in which case they set the path variables and then call perl with the passes args.

The code is at https://github.com/StrawberryPerl/Perl-Dist-Strawberry/blob/master/share/portable/portableshell.bat

shawnlaffan avatar Jul 16 '25 23:07 shawnlaffan

Thanks you both. To resolve a binary mismatch issue with the XS module, we switched to using the GCC and G++ toolchain bundled with Strawberry Perl. This resolved the runtime errors, suggesting that the compiler used must tightly match the Perl interpreter's build environment.

However, the rest of our project builds with the MSYS2 system GCC(15.1.0). Is it possible to build a compatible Perl XS module using a different GCC (e.g., MSYS2's) instead of the one bundled with Strawberry Perl? Or is matching compilers strictly required for ABI compatibility?

Would appreciate any guidance or clarification on this.

alanoflanagan avatar Jul 17 '25 11:07 alanoflanagan

I gather that your MSYS2 gcc.exe is the one that gets installed into your MSYS2/usr/bin folder. Shawn is probably more knowledgeable about MSYS2 than me, but I doubt that this particular gcc will ever be compatible with Strawberry Perl (or any other native Win32 build of perl). You can, however, also have pacman install a build of gcc into your MSYS2/mingw64/bin - and that gcc should be compatible with Strawberry Perl and its gcc. Even if the 2 gcc's are a different version, I think you would be unlucky to hit any issues. (No guarantees, of course.)

Alternatively, if you open up MSYS2's mingw64.exe shell (instead of the msys2.exe shell) you'll be able to use Strawberry Perl's compiler (or any of the 64-bit compilers available from https://winlibs.com) in that mingw64.exe shell.

In my MSYS2 installation, gcc is nowhere to be found. But in MSYS2's mingw64.exe shell, I'm currently using gcc-15.1.0 (UCRT) from winlibs to build various libraries for use with my native Win32 build of perl-5.42.0. That perl was built by the very same compiler in the cmd.exe shell. (I think Strawberry Perl takes essentially the same approach ... but Shawn would definitely no more about that ;-)

sisyphus avatar Jul 17 '25 15:07 sisyphus

Strawberry Perl's libs are built in an MSYS2 shell where the winlibs gcc and libs are at the front of the path.

Compiling other libs using the MSYS2 mingw64 gcc should work so long as they use the same C runtime - for SP 5.40 and later this is UCRT.

I've been using Gtk3 DLLs extracted from MSYS2 for a while now (courtesy Rob's process at PerlMonks. The extracted files are at https://github.com/shawnlaffan/perl-alien-gtkstack-windows if anyone is interested. It currently has the MSVCRT versions so SP 5.38 or earlier is needed. There are also PPMs but for 5.38 only.

shawnlaffan avatar Jul 17 '25 22:07 shawnlaffan

Unfortunately I work with a large codebase with multiple dependencies that are tightly coupled to the legacy MSVCRT runtime. Due to compatibility constraints, migrating to UCRT is not currently feasible for our environment.

I understand that recent versions of Strawberry Perl (5.40+) are built using UCRT-based toolchains and dependencies. Is it possible to rebuild or configure the build system to support MSVCRT instead or could you advise on how we could get around this mismatch issue?

alanoflanagan avatar Aug 07 '25 16:08 alanoflanagan

I've sent off a post to perl 5 porters list, seeking clarification on what the "loadable library" (referred to in the handshake error) is - and also what information the values of the 2 hex strings actually convey to us.

My belief is that the "loadable library" refers specifically to the perl dll (eg perl540.dll or perl538.dll) and that the perl binaries refer to files built by and for perl. That is, I'm seeing it as an internal perl error - the sort of thing that could happen if you uninstalled a Strawberry 5.38.4 msi installation and replace it with a Strawberry 5.40.0 msi build. (It might happen because a part of 5.38.4 has been left behind, and the new 5.40.0 installation tries to access some of those 5.38.4 binaries.)

But I don't know ... maybe the "loadable library" can be any dll - even one of those outside of the perl installation.

If the problem really is as you believe, then you'll need a perl built by using one of the MSVCRT 64-bit compilers from https://winlibs.com. The build itself is quite simple, but it won't have any of the modules that ship in Strawberry's vendor/lib folder. Would the absence of those modules be a problem for you ?

sisyphus avatar Aug 08 '25 04:08 sisyphus

Strawberry Perl 5.40 onwards uses UCRT because it fixes several issues with locale handling. See for example #150 and #119

It is, however, possible to adapt a 5.4x build config to use the MSVCRT.

Change the Perl::Dist::Strawberry::Step::BinaryToolsAndLibs section to match the equivalent section from the 5.38.4.1 config.
https://github.com/StrawberryPerl/Perl-Dist-Strawberry/blob/b672ef3bc6d16ac271334041ba994fc1836feb01/share/64bit-5.42.0.1.pp#L20-L64

Change the target perl source at https://github.com/StrawberryPerl/Perl-Dist-Strawberry/blob/b672ef3bc6d16ac271334041ba994fc1836feb01/share/64bit-5.42.0.1.pp#L80

Then edit/elide the various Perl::Dist::Strawberry::Step::InstallModules steps as needed.

Then update one of the build scripts to make life a little easier when running the build, e.g. https://github.com/StrawberryPerl/Perl-Dist-Strawberry/blob/master/devel.utils/_build-5.42.0_local.bat

shawnlaffan avatar Aug 08 '25 04:08 shawnlaffan

Thanks for your reply's. @sisyphus Im not too sure if absence of those modules will be a problem but I think ill have to run the integration tests.

@shawnlaffan And for the second step what is the target perl source. If it perl 5.38.4 will we be stuck on the versions before perl 5.40 in the future

alanoflanagan avatar Aug 08 '25 15:08 alanoflanagan

And for the second step what is the target perl source. If it perl 5.38.4 will we be stuck on the versions before perl 5.40 in the future

This can be whatever you choose. If you want to use 5.42 then the example I gave will work. Otherwise update for whatever your target is.

Your aim, as I understand it, is to get a recent perl built with MSVCRT. The only reason I noted the external libs from 5.38 is that they are built using MSVCRT.

Note that I'm unlikely to update the MSCVRT external libs as we are using UCRT now. This means there will be eventual bit-rot but they should be fine for a while. You also only need to include the ones needed for the perl modules you are building (I would assume you do not need a full Strawberry distribution).

shawnlaffan avatar Aug 09 '25 08:08 shawnlaffan

I've tried (but failed) to get a handshake error when a UCRT perl loads an MSVCRT dll.

Generally, I'm finding no problem with that, but one caveat is that if a (UCRT) perl filehandle is passed to an (MSVCRT) dll function that accepts a FILE* argument, then it will likely (inevitably ?) crash because the pointer is to a location that only the UCRT can know about. I can reproduce that issue by trying to build Math::MPFR on a UCRT perl against a shared MPFR library (dll) built by an MSVCRT compiler. Most of the MPFR functionality is accessible, but any MPFR function that accepts a FILE* argument will crash if an attempt is made to use it. The crash happens silently - there's no "handshake" error encountered to catch this.

One solution is to use the MSVCRT compiler to build a static library, and then have (UCRT) perl build against that static library. In that case the (UCRT) filehandle never gets passed to the MSVCRT, and all is fine. (I suspect that this solution is also untenable in @alanoflanagan's case.) Otherwise, it's a matter of ensuring that the same runtime that was engaged in building the dll, was also engaged in the building of perl - which is precisely what @alanoflanagan is embarking upon.

It's the fact that I can't find a way to trigger the "handshake" error through a runtime mismatch that reinforces my view that the handshake error that @alanoflanagan is seeing occurs because of something other than that mismatch. (I could, of course, be wrong ... ;-)

Good luck with it, Alan. Let us know how it goes,

sisyphus avatar Aug 09 '25 09:08 sisyphus

Yeah that 5\n was the same output i was seeing in the 5.38v. I am using strawberry-perl-5.40.2.1-64bit-portable.zip but am building msys2 mingw64 env. This has a system perl which is 5.38.2 version. I have renamed that exe so it is no longer visible. I don't want the system perl to be used. And all the paths look correct below.

The root perl.exe its perl5xx.dll, its /lib, its /lib/Config.pm', /lib/Config_heavy.pl', /lib/CORE, /lib/auto, and its /site/lib and /vendor/lib, and all CPAN modules you build/install yourself later on, are 1 un-separably set/group/collection.

perl.exe its perl5xx.dll, and all CPAN XS .dlls under no circumstance can be copy pasted between different perl versions or different build configs of the same major version. NO min"n"match!

The 1 and only exception is, you can upgrade the perl.exe and perl5xx.dll, to a higher maint release, if it exists. The XX in 5.XX.Y can never be mismatched. You have recompile all your CPAN XS .dlls. The exception is, the Y in 5.XX.Y, can go from 0 to 1, or 1 to 2, and XX MUST be an even number, and not "blead perl" which has an odd XX number.

Also, I have ZERO trust, that ABI compatibility exists between all forks, packagers, builders, vendors, distributors, of any version or build number of Mingw.org or of any version or build number of Mingw-64. I would never attempt to compile an XS .dll with a "newer" GCC or "not Strawberry's GCC".

Cygwin GCCs and Msys GCCs are straight up alternate OSes/alternate ABIs/calling conventions/alternate CPU architectures in my book, compared to Mingw GCCs. Your are trying to compare iOS vs Linux. Or Android vs Debian.

Al 4 are POSIX OSes, yes grepping the NVM/SATA drive will show all 4 have the same exact spelling POSIX function calls written 7 bit ascii somewhere on their NVM/SATA drivers. But that doesn't have anything to do with why you can't double click the same POSIX binary file on all 4 to launch your process (lets ignore all assembly ABI Kernel voodoo like Cosmopolitan Perl/Cosmo Libc SDK).

Cygwin's and Msys's .h headers, and their bundled GCC binaries's default settings (aka -dumpspecs) are very different from what the defaults are in Mingw.org GCCs or Mingw-64 GCCs and Strawberry. Mingw GCC is for 100% Win32 aware non-POSIX C/C++ code. Cygwin and Msys are designed for source code compatibility with Windows-unaware C/C++ source code.

With great difficult, and certain kernel32.dll/ntdll.dll fn calls being permanently broken/disabled/erroring out inside a Cyg or Msys process because Cyg/Msys's Libc or "Runtime" changed alot of secret settings inside that Win32 process, to maximize POSIX behavior, and keeping Win32-features working is against the point of those runtime enviroments. Yes it it is possible to link against and execute a fn call from kernel32.dll/ntdll.dll inside a Cyg/Msys proc, but whats the point?

Use the where tool

C:\sources\perl5\win32>where
The syntax of this command is:

WHERE [/R dir] [/Q] [/F] [/T] pattern...

Description:
    Displays the location of files that match the search pattern.
    By default, the search is done along the current directory and
    in the paths specified by the PATH environment variable.

Parameter List:
    /R       Recursively searches and displays the files that match the
             given pattern starting from the specified directory.
    /Q       Returns only the exit code, without displaying the list
             of matched files. (Quiet mode)
    /F       Displays the matched filename in double quotes.

to figure out which gcc.exe or g++.exe is actually executing. Again, I would never use a different GCC binary toolchain against any Strawberry Perl, than the GCC binaries and .h files, that that Strawberry came with.

Each Win32 Perl build, both WinGCC Perl and MSVC PERL, have permanently burned in settings inside the perl.exe/perl5xx.dll/Config.pm/lib/CORE/config.h/Config_heavy.pl files, from the exact MSVC or GCC compiler binary that was used at the time those 5 files were created. There is a tiny bit of forwards and backwards lee-way when compiling an XS .dll later on. MSVC Perls are historically very tolerant of forwards/backwards MSVC major CC changes between the MSVC version used to make perl5xx.dll and the MSVC version used to make Foo.xs.dll 6 months later.

But I've never heard of, or seen any patches, or attempts at WinGCCPerl Forwards/backwards mix'n'matching of GCC major version or GCC binary packagers/distributors. Its just not a thing. No WinGCCPerl users are interested in such a thing. They would just download a newer Strawberry Perl major version and be done with it in 5 minutes. Its probably officially not supported if you would make a P5P bug ticket, to force the policy on that question.

Of course patches are welcome for 20-25 years of Mingw 2.95 to Mingw 1450.0 ABI runtime machine code interoperability.

bulk88 avatar Aug 12 '25 21:08 bulk88

Generally, I'm finding no problem with that, but one caveat is that if a (UCRT) perl filehandle is passed to an (MSVCRT) dll function that accepts a FILE* argument, then it will likely (inevitably ?) crash because the pointer is to a location that only the UCRT can know about. I can reproduce that issue by trying to build Math::MPFR on a UCRT perl against a shared MPFR library (dll) built by an MSVCRT compiler. Most of the MPFR functionality is accessible, but any MPFR function that accepts a FILE* argument will crash if an attempt is made to use it. The crash happens silently - there's no "handshake" error encountered to catch this.

DO NOT WRITE #define NO_XSLOCKS, you got what you asked for which is DIY explicit manual MS CRT pointer management. Perl's Newx() and Perl's PerlIO identifiers/APIs have never and will never be #defines to theabstract unnamed libc .so/.dll file that was the exact disk file a hello_word.c process compiled on the same box was using under the hood. Its easier to say libperl implements its own libc which has nothing to do with the "generic" libc that came with your OS's .iso.

https://github.com/Perl/perl5/blob/blead/XSUB.h#L487

Perl's Newx() and Perl's PerlIO ptrs are not compatible with anything but libperl, they aren't synonyms to any other MS CRT or POSIX "libc" shared library. Libperl has its own allocator and dtor and in-use and free pool algorithms for Newx() and PerlIO ptrs.

One solution is to use the MSVCRT compiler to build a static library, and then have (UCRT) perl build against that static library. In that case the (UCRT) filehandle never gets passed to the MSVCRT, and all is fine. (I suspect that this solution is also untenable in

Static CRTs basically solve nothing except 1 click no installation procedure portable .exe file feature.

A static CRT will create another unique pool of malloc() ptrs, that SEGV when they appear in the free() symbol of another CRT, and another pool of more 0-based fileno() FDs and another pool of FILE * that are overlapping but failing/SEGVing in random places.

And imagine the .def .a .lib logistics, to make a static CRT's function symbols appear in your .dll's export table, so an upstream or downstream consumer or producer .dll can create and dtor you new unique pools of 0-based fileno() FDs, FILE *, and malloc() ptrs.

WinPerl's 2 solutions to the 2 MS CRT versions in 1 address space problem, and this was solved decades ago.

Use XSUB.h to C preprocessor hook all the generic MS/POSIX libc symbols, to Perl's DIY-ed alternatate implementation of libc front end. The full list of symbol/macro names of the "front end" of LibPerlC is located at

https://github.com/Perl/perl5/blob/blead/iperlsys.h

The pointers from iperlsys.h and usually be injected/safely released back into the Perl VM, at the CV*/ XSUB / PUSHs / ST(0) / SV*level.

If you want to invoke function pointers/function calls, on the EXACT SAME, abstract, unnamed MS CRT, that perl5xx.dll is using, there are dozens of win32_f_m_str_mem_something() exported symbols from perl5xx.dll,which are jump stubs to whatever MS CRT binary perl5xx.dll is connected to. Read this list for a full list names.

https://github.com/Perl/perl5/blob/blead/win32/win32iop.h

If there is a function you want to call in "Abstract Unknown MS CRT" not listed in, win32iop.h, and me and I'll cook up some C code to make perl5xx.dll and kernel32.dll cough up the HMODULE pointer of the unnamed MSCRT that perl5xx.dll imported with its import take. Then you can GetProcAddress() whatever you want and learn the full disk fiile name of that unnamed MSCRT. I've wanted for years to add to WinPerl a discrete feature/new tiny C function, for WinPerl to tell a CPAN XS author/his .dll, the HMODULE of the MS CRT that the perl5xx.dll is connected to but ive never had the time.

The Hmodule of the MS CRT WinPerl is using, can be obtained currently with about 1/2 to 1.5 pages of C code and a couple kernel32.dll calls.

Worst case scenario, you might need 3 Translation Units, a ExtUtils::ParseXS .xs TU, a neutral CRT independent .c TU with alot of extern function calls, and finally a 3rd .c TU that interacts with the 3rd party msvcrt.dll-only library. And you carefully double-buffer between the foreign perl-unaware C library 3rd party ptrs, and perl5xx.dll's ptrs/SV*s allocators.

This is not the hardest thing in the world. Every SQL/GTK/QT/TK/Javascript CPAN XS module already does this double buffering between SV*s/Newx ptrs and foreign SQL/GTK/QT/TK/Javascript ptrs.

There are no engineering/technical reasons or limitations in the Win32 PE Specification/WinOS arch, that would prevent 1 .dll, from linking to and executing malloc() from msvcrt.dll malloc() from msvcr80.dll and malloc() from msvcr120.dll,all in the same .dll file. Its very complicated to do in C lang, it will require custom .def. files and using lib to make you own custom .lib files, and multiple translation units aka .c files, but the Win32 PE Spec has no problems with linking in 3 malloc() identical string names from 3 different named CRT .dll files.

Basically the CPAN side XS .dll and its children libs are 100% recompiled from source code, with #defines to Perl's Newx API, or the CPAN side XS .dll carefully double buffering or double copies between the 2 sides. SvLEN() == 0, sv_magicext(), SvREADONLY_on(), SvGETMAGIC, SvSETMAGIC(), overload.pm, TIEARRAY, TIEHASH` are the common tools used to do double buffering or double copying.

bulk88 avatar Aug 12 '25 22:08 bulk88

Strawberry Perl's libs are built in an MSYS2 shell where the winlibs gcc and libs are at the front of the path.

Compiling other libs using the MSYS2 mingw64 gcc should work so long as they use the same C runtime - for SP 5.40 and later this is UCRT.

I've been using Gtk3 DLLs extracted from MSYS2 for a while now (courtesy Rob's process at PerlMonks. The extracted files are at https://github.com/shawnlaffan/perl-alien-gtkstack-windows if anyone is interested. It currently has the MSVCRT versions so SP 5.38 or earlier is needed. There are also PPMs but for 5.38 only.

I looked at the binaries inside https://github.com/shawnlaffan/perl-alien-gtkstack-windows/releases/download/Gtk3_20250624/from_mingw.zip .They are all linked/connected to msvcrt.dll.

If I had to fix this, I'm not going invest in "alot of stick, and 1 micron of carrot" beating the GCC/MSVC/ISO C software stacks to Win32 PE Imp/Exp table link in the theoretical absolute perfection way to save a couple milliseconds on startup of my XS .dll.

Instead the no headaches way is

https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulehandlew

HANDLE h = GetModuleHandleW(L"msvcrt.dll");

and then I write 2-5 pages of .pl code, to automate writing out .c code with 25-50 macros and 200-250 lines of C code using

https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress

and then just manually calling msvcrt.dll fn symbols exactly where I want to in my .xs file.

I have full control over the transition layer between "closed source" binary blob GTK .dll'es and the Perl XS/SV* APIs. Gor this GH comment and this bug ticket, GTK is a closed source proprietary commercial Win32 library with an official SDK for embedders/plugin writers. This is not a challenge on WinOS.

Its alot of #defines tho, and requires writing a medium to medium-short .pl that emits .h or .c code.

Its normal on Windows OS platform to have to code against other corporation's proprietary binary blobs + their official SDK .h files that they give their customers.

bulk88 avatar Aug 12 '25 22:08 bulk88

5th option, which I would vote "no" on, is https://dynamorio.org/ https://github.com/microsoft/Detours and all your basic very dark shade of grey runtime binary hook/patching/machine code rewrite solutions. Note ucrtbase.dll and the older generation of msvcrt.dll-msvcr130.dll can not be swapped with a hex editor changing string msvcrt.dll to ucrtbase.dll.

More than just that would need to be done. Its alot of work, but could be done,and I still wouldn't feel comfortable seeing it in Strawberry Perl.

UCRT's exported symbol __stdio_common_vfprintf's ABI and C API and C prototype is unrecognizable, compared to ISO C's and POSIX's and msvcrt.dll-msvcr130.dll 's vfprintf() or _vfprintf() symbol.

UCRT aware CCs static link into consumer .dlls a tiny static not inline shim to convert from normal AnyOS "C" std lib functions like vfprintf(), to UCRT's ultra-proprietary pubternal "C++ese" __stdio_common_vfprintf' linker/exp table symbol.

Dynamic runtime patching, egh, it can be safe, its normalized at some SW companies/employers by now. MS does, all their MVP/VAR clients do it. MS's AppCompat DB does it. Its "normalized" by now. But Strawberry Perl is supposed to be a production grade, server safe, no baby sitting by a sysadmin, piece of software. Its supposed to be deploy it to non-IT employees workstations and walk away without 2nd thoughts and "what ifs".

GetModHandle/GetProcAddr, is always much safer and lower risk than messing with i386/amd64 machine code. Yes some people, many people, can safely mess with dynamic runtime hooking, but why do it here, if there is a no-assembly lang alternative?

Is there some super critical API/back compat requirement for bare 0-based signed int fileno()s to be interchangeable between GTK/Glib pure-c layer and Perl's PP high level PerlIO API or PP keywords open/read/write/close/<>/sysread/syswrite/fdopen/ioctl?

bulk88 avatar Aug 12 '25 22:08 bulk88