Steve Hay wrote:
> In a couple of my XS modules I've long hand some rudimentary checks in
> place to disallow building with a different compiler suite to that
> which perl was built with, e.g. to disallow building with VC12 when
> perl was built with VC6.
>
> It has been mentioned to me several times over the years that there
> should not be a problem with using a different compiler suite so the
> checks are unnecessary, and I've finally got round to having a look...
>
> It seems to be true in general that there is no problem, but there is
> at least one thing that can go wrong due to VC7 and higher using
> versioned C RTL DLLs (msvcr70.dll etc instead of msvcrt.dll) so that
> two different C RTLs may get loaded (one by perl and a different one
> by the XS module): If you use a mix of CRT I/O functions, some of
> which are redirected by perl and others not, then you can end up
> passing a file descriptor that was opened in one C RTL to the other C
> RTL, which knows nothing about it.
>
> This can happen, for example, if you obtain a file descriptor using
> _sopen() (a Microsoft-specific variant of open(), which PerlIO doesn't
> redefine) and pass it to close() (a standard C function, which PerlIO
> does redefine). In this case the XS module's C RTL opens the file
> descriptor, but because close() is redefined to a call within perl it
> is perl's C RTL that is asked to close it, which will fail if that's a
> different C RTL.
>
This is documented by MS.
http://msdn.microsoft.com/en-us/library/ms235460.aspx
> A similar thing can happen when mixing Windows API functions
> (obviously not redefined by perl) with standard C functions, e.g.
> opening a file descriptor with open() (using perl's C RTL) and then
> passing it to _get_osfhandle() (in the XS module's C RTL).
>
> I have found cases exactly like the above in my code and am in the
> process of fixing them (either by using exclusively standard C
> functions, all redefined by perl, or else by using exclusively
> Microsoft-specific functions, none redefined by perl), but I have run
> into another problem which causes certain combinations of VC++
> versions to fail.
Then dont mix up CRTs in the first place. There are also the win32_*
functions that are exported that redirect to Perl's CRT DLL if you want
the same CRT as Perl.
>
> One module crashes when using a member of the MY_CXT structure;
> another crashes when calling chsize(), which is redefined as
> (*my_perl->ILIO->pChsize)() when PERL_IMPLICIT_SYS is defined. In each
> case, the struct member being used (MY_CXT.err_str in the former case;
> my_perl->ILIO->pChsize in the latter case) is unexpectedly NULL
> (0x00000000) with some combinations of C RTL DLLs.
Show the entire MY_CXT struct you created. Remember a MY_CXT struct can
never leave the compiland it was defined in. They are effectivly C
static declared. There is also win32_chsize. And NO_XSLOCKS define. If
my_perl->ILIO->pChsize (a vtable entry) is NULL, the problem is
somewhere in Perl, or your embeddeding code of Perl interp. I dont
understand "MY_CXT.err_str" to comment on that. If you have an
unthreaded Win32 Perl, my_perl is still a valid C symbol, but if you use
it, you will be broiled ;)
http://perl5.git.perl.org/perl.git/blob/HEAD:/perl.h#l4894 .
>
> The crashes only happen when using a perl built with VC8 or higher and
> using VC6 or VC7 to build the XS modules. Fortunately, that's an
> unlikely combination: If you have a VC8 or higher perl then you
> probably built it yourself, so you would probably build the XS module
> with the same version of VC++.
>
> Mismatches the other way around do not seem to pose any problem, e.g.
> a VC6 build of perl with VC12 being used to build the XS module.
> (Which is good, since that's a more likely scenario, e.g. ActivePerl
> used to be built with VC6, and is now built with a gcc port that also
> uses msvcrt.dll like VC6 did.)
>
> It would still be nice to understand what the problem is though. I'm
> not sure if it's something I'm doing wrong, something wrong in perl, a
> compiler bug that was fixed in VC8, or just some other fundamental
> incompatibility between <=VC7 DLLs and >=VC8 DLLs?
>
> The attached module illustrates the problem.
>
I'll try running it with a VC 2008/9.0 Perl with VC 2003/7.0 XS DLL.
> Using a VC8 or higher build of perl but trying to build this module
> with VC6 or VC7 causes both tests to fail:
>
> C:\Dev\Temp\Foo-1.00>perl -Mblib t\test.t
> 1..2
> # pOpen() is 00000000
> not ok 1
> # Failed test at t\test.t line 7.
> # buf is 00000000
> not ok 2
> # Failed test at t\test.t line 8.
> # Looks like you failed 2 tests of 2.
>
> Using the same VC8 or higher build but now using VC8 or higher (but
> not necessarily the same as was used for perl) to build this module is
> fine:
>
> C:\Dev\Temp\Foo-1.00>perl -Mblib t\test.t
> 1..2
> # pOpen() is 61931230
> ok 1
> # buf is 003479A4
> ok 2
>
> Using a VC6 or VC7 build of perl is also fine, whatever version of
> VC++ is used to build this module.
>
> Can anyone explain what the problem here could be? Is it something
> that I or we (p5p) could fix, or is it just a compiler problem that we
> can't do anything about?
Can you attach your VC6/VC7 Foo.dll binary/DLL for me to look at?