On Fri, 2005-01-14 at 15:29, Steve Hay wrote:
> Jonathan Stowe wrote:
> 
> >On Fri, 2005-01-14 at 11:31, Jonathan Stowe wrote:
> >  
> >
> >>On Thu, 2005-01-13 at 18:52, [EMAIL PROTECTED] wrote:
> >>    
> >>
> >
> >  
> >
> >>>GetConsoleMode failed, LastError=|6| at blib\lib/Term/ReadKey.pm line 265.
> >>>END failed--call queue aborted.
> >>>NMAKE : fatal error U1077: 'C:\WINDOWS\system32\cmd.exe' : return code 
> >>>'0x9'
> >>>Stop.
> >>>
> >On further examination I have distilled it down to:
> >
> >Test.xs:
> >
> >        #include "EXTERN.h"
> >        #include "perl.h"
> >        #include "XSUB.h"
> >        
> >        #include "ppport.h"
> >        #include <io.h>
> >        
> >        MODULE = Test                PACKAGE = Test          
> >        
> >        
> >        void Test(fh)
> >             PerlIO *fh
> >             CODE:
> >        {
> >             int handle;
> >             HANDLE hwnd;
> >             handle = PerlIO_fileno(fh);
> >        
> >             if ((hwnd = (HANDLE)_get_osfhandle(handle)) == -1)
> >                     croak("bad file handle");
> >        }
> >
> >Test.t:
> >
> >        use Test
> >        use Fcntl;
> >        
> >        sysopen( IN,  'CONIN$',  O_RDWR );
> >        
> >        Test::Test(IN);
> >        
> >Which croaks with the message as above.
> >
> >In normal usage CONIN$ and CONOUT$ work normally ( I can read, print and
> >take their fileno()).
> >
> >So my question is: am I looking at a bug in the MS CRT here ( I am
> >testing with "Microsoft (R) 32-bit C/C++ Optimizing Compiler Version
> >13.10.3077" i.e. the one that comes with Visual Studio 2003 ) and if so
> >are there any workarounds, or is this something strange (bug,
> >undocumented behaviour?) with PerlIO or indeed (quite likely) something
> >that I have missed and/or failed to understand. It occurs to me that it
> >could be something that is happening when the extension is compiled with
> >a diversion version of the compiler and/or CRT from that which compiled
> >the Perl but I am not in a position to test this right now.
> >
> >Any input welcomed, especially testing with various MS compiler and Perl
> >versions.
> >
> I suspect that the problem is using the VC7 (aka Visual Studio 2003) 
> compiler with ActivePerl, which is built with VC6 (aka Visual Studio 98).
> 
> I've had error reports from the same cpan-tester in which this turned 
> out to be the problem, e.g. see:
> http://www.mail-archive.com/cpan-testers@perl.org/msg157084.html
> 
> I tried your module using ActivePerl Build 810 and VC7 and got the same 
> error.  Retrying with ActivePerl Build 810 and VC6 it works fine.  
> Trying again with VC7 but now using my own build of Perl also done with 
> VC7 it also works fine.
> 

Yep, I can confirm this having had the opportunity to build a Perl on
windows.

> So it certainly looks like a CRT conflict in the ActivePerl/VC7 scenario 
> -- any time that you pass CRT resources between the msvc71.dll loaded by 
> your module's DLL and the msvcrt.dll loaded by ActivePerl's DLL you will 
> get problems.  For example, in your XS above you open a file via 
> msvcrt.dll (the sysopen in Perl) and then pass the handle to msvc71.dll 
> (your XS code).  The latter CRT doesn't think that the handle opened by 
> the former CRT is valid.
> 

I think I must have been having a thick(er) moment on friday - on
inspection of the CRT source in the Windows SDK it is apparent that the
fileno is an index into an array of structs that holds among other
things the windows HANDLE to the file and that this array is static to
the instance of the CRT, so when you are using two separate CRT dlls
they are not going to have the same static information. I think I
already knew this :-(

> The only "solution" that I've come up with in cases where sharing CRT 
> resources in this way is unavoidable is to recommend that users use the 
> same compiler to build my modules as was used to build Perl.  I don't 
> even have a good way of checking for this, so I just have a note in my 
> INSTALL file to this effect.
> 

In this particular case  (building an extension using a different MS C
compiler than that which built ActivePerl) it would be possible to
determine the particular build and the version of the C compiler you are
going to use (either by compiling and running a small program that
output the value of _MSC_VER or by examining CL.EXE's banner) and then
exit Makefile.PL with a message if they are incompatible.  In the more
general case it becomes more difficult.

> If anyone has any better solutions, I'd love to hear them!
> 

In principle would it be possible to determine the compiler and/or CRT
version at configure time and make that available to test in cases like
this?

Reply via email to