Steve Hay <[EMAIL PROTECTED]> writes:
>Hi,
>
>I'm having trouble trying to use the PerlIO_binmode() function in my XS 
>code.  I'm working on Windows (XP), so this function is not a no-op.
>
>A file is opened in "text mode" by a library function that returns a 
>FILE *.  

That is the problem.

>I call PerlIO_importFILE() to get a PerlIO *, then call:

Did you pass in the correct "mode" ?
 e.g. PerlIO_importFILE(f,"wt");

It is _possible_ that if PerlIO is told file is in text mode 
it may actually act on a PerlIO_binmode() to put in into binary.
But I had not thought of that case so if it works it is just 
due to "regular" coding ...


>
>    PerlIO_binmode(p, type, O_BINARY, Nullch)
>
>to put the file handle into "binary mode", and then call PerlIO_printf() 
>and PerlIO_close().  The data printed to this file handle was "Hello, 
>world.\n", but when I look at the file that has been created it ends 
>with "\r\n" -- i.e. "text mode" translation has been performed on the 
>data.  This was not what I expected.  Have I mis-interpreted what the 
>PerlIO_binmode() call is supposed to do, or is this broken?

PerlIO_binmode puts PerlIO into binmode ;-) 
Your problem is that the underlying FILE * is translating.
When PerlIO uses stdio (and it does NOT by default on Win32) it always
opens FILE * as binary.

>
>As an experiment, I tried changing the above PerlIO_binmode() call to 
>the following:
>
>    PerlIO_binmode(p, type, O_TEXT, ":crlf")
>
>I thought this would be a no-op, putting the file handle into "text 
>mode" when it already is, but I found that the file created now ends 
>with "\r\r\n" -- i.e. two rounds of "text mode" translation now appear 
>to have been performed.

Yup.

>
>Is this all something to do with the new PerlIO "layers"?  Am I simply 
>adding more layers to the existing "text mode" layer?  If so, then how 
>do I remove that existing layer so that the file handle is (just) 
>"binary mode"?

Open the FILE * as binary in the XS code before importing it?


>
>The above all relates to a Perl that I've built myself (without 
>PERL_IMPLICIT_SYS).  If I try and use ActivePerl instead (which has 
>PERL_IMPLICIT_SYS) then the module won't even build:
>
>    warning C4047: 'function' : 'struct interpreter *' differs in levels 
>of indirection from 'struct _PerlIO ** '
>    warning C4024: 'PerlIO_binmode' : different types for formal and 
>actual parameter 1
>    warning C4047: 'function' : 'struct _PerlIO ** ' differs in levelsof 
>indirection from 'char '
>    warning C4024: 'PerlIO_binmode' : different types for formal and 
>actual parameter 2
>    warning C4047: 'function' : 'int ' differs in levels of indirection 
>from 'char *'
>    warning C4024: 'PerlIO_binmode' : different types for formal and 
>actual parameter 4
>    error C2198: 'PerlIO_binmode' : too few actual parameters
>
>Why is this?

Same kind of mess that you had with your other questions.
There is:

int perlsio_binmode(FILE *fp, int iotype, int mode);

in the non-PerlIO body of perlio.c

Which should probably have been exported via PerlSIO_binmode().
It _attempts_ to put a FILE * into binmode. Note thete are problems 
with that in general - which is why PerlIO normally avoids stdio on 
CRLF platforms, and starts all FILE * in binmode when forced to use it.

The main snag is that (typically) once a single octet is sent to the stream
it is locked into a mode ...

It would seem that PerlStdio_binmode should not just be the 
"base" binmode but replicate that (or call it) - will look at it for 5.8.1


It seems that ActivePerl (or any 5.8.0 Win32 PERL_IMPLICIT_SYS perl) is not 
really ready for stdio/PerlIO co-existance from XS code yet.
This is not a complete surprise - it is very new and has a few rough 
edges even in the much simpler UNIX world.


>
>Thanks,
>
>Steve
-- 
Nick Ing-Simmons
http://www.ni-s.u-net.com/

Reply via email to