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/
