Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: How to receive a FILE* from Python under MinGW?

Reply
Thread Tools

Re: How to receive a FILE* from Python under MinGW?

 
 
Gabriel Genellina
Guest
Posts: n/a
 
      03-21-2007
En Wed, 21 Mar 2007 00:46:03 -0300, John Pye
<(E-Mail Removed)> escribió:

> This is not an option for me, as I want to pass the
> FILE* from Python and all the way into into a existing shared-library
> code. I can't change the latter; it must work ok with standard fprintf
> (etc) functions.


You can get the file descriptor from the Python file object using its
fileno() method. The file descriptor lives at the OS level, so it's safe
to pass around. You can regenerate a new FILE struct (using the other
runtime library) with fdopen.


--
Gabriel Genellina

 
Reply With Quote
 
 
 
 
John Pye
Guest
Posts: n/a
 
      03-21-2007
On Mar 21, 3:15 pm, "Gabriel Genellina" <(E-Mail Removed)>
wrote:
> En Wed, 21 Mar 2007 00:46:03 -0300, John Pye
> <(E-Mail Removed)> escribió:
>
> > This is not an option for me, as I want to pass the
> > FILE* from Python and all the way into into a existing shared-library
> > code. I can't change the latter; it must work ok with standard fprintf
> > (etc) functions.

>
> You can get the file descriptor from the Python file object using its
> fileno() method. The file descriptor lives at the OS level, so it's safe
> to pass around. You can regenerate a new FILE struct (using the other
> runtime library) with fdopen.
>
> --
> Gabriel Genellina


Hi Gabriel

Are you sure about this? My understanding is that 'fileno' is just a
FILE* cast to an integer. So it's a pointer to something (check out
stdio.h to see what it points to). Problem is (AFAICT) that Python 2.4
uses a different version of the C runtime DLL (MSVCRT*.DLL) to that
which MinGW links against. And it turns out that the different C
runtime libraries have incompatible implementations of the FILE
struct. And therefore if you try to pass a FILE* (fileno?) from Python
to MinGW you will get a segfault.

If there is more to your suggestion that I'm not seeing, please
clarify. Have you tried this with MinGW actually?

Cheers
JP

 
Reply With Quote
 
 
 
 
John Pye
Guest
Posts: n/a
 
      03-21-2007
On Mar 21, 3:15 pm, "Gabriel Genellina" <(E-Mail Removed)>
wrote:
> En Wed, 21 Mar 2007 00:46:03 -0300, John Pye
> <(E-Mail Removed)> escribió:
>
> > This is not an option for me, as I want to pass the
> > FILE* from Python and all the way into into a existing shared-library
> > code. I can't change the latter; it must work ok with standard fprintf
> > (etc) functions.

>
> You can get the file descriptor from the Python file object using its
> fileno() method. The file descriptor lives at the OS level, so it's safe
> to pass around. You can regenerate a new FILE struct (using the other
> runtime library) with fdopen.
>
> --
> Gabriel Genellina


Hmm. Reading this again I think I understand properly now. The
'fileno' is really *not* the same thing as the FILE* pointer cast to
an integer. It is a lower-level structure.

The question is now, if I don't want to modify my *python* code, how
do I get at the 'fileno' property of my PyFileObject?

Also, are there consequences for using this approach of regenerating
the FILE struct? For example if I have the following:

F = os.tmpfile()
F.write("some data")
F.seek(0)
myswigmodule.dosomething(F)
F.seek(0)
S = F.read()
print S

I don't know enough about this low-level file handling to really
understand the implications of what you are proposing -- perhaps you
could explain a little?

Cheers
JP

 
Reply With Quote
 
Ross Ridge
Guest
Posts: n/a
 
      03-21-2007
Gabriel Genellina <(E-Mail Removed)> wrote:
>You can get the file descriptor from the Python file object using its
>fileno() method. The file descriptor lives at the OS level, so it's safe
>to pass around.


Not under Windows. Windows doesn't have Unix-like descriptors, so the
C runtime emulates them.

Ross Ridge

--
l/ // Ross Ridge -- The Great HTMU
[oo][oo] http://www.velocityreviews.com/forums/(E-Mail Removed)
-()-/()/ http://www.csclub.uwaterloo.ca/~rridge/
db //
 
Reply With Quote
 
Gabriel Genellina
Guest
Posts: n/a
 
      03-21-2007
En Wed, 21 Mar 2007 01:30:34 -0300, John Pye <(E-Mail Removed)> escribió:

> On Mar 21, 3:15 pm, "Gabriel Genellina" <(E-Mail Removed)>
> wrote:
>> En Wed, 21 Mar 2007 00:46:03 -0300, John Pye
>> <(E-Mail Removed)> escribió:
>>
>> > This is not an option for me, as I want to pass the
>> > FILE* from Python and all the way into into a existing shared-library
>> > code. I can't change the latter; it must work ok with standard fprintf
>> > (etc) functions.

>>
>> You can get the file descriptor from the Python file object using its
>> fileno() method. The file descriptor lives at the OS level, so it's safe
>> to pass around. You can regenerate a new FILE struct (using the other
>> runtime library) with fdopen.
>>
>> --
>> Gabriel Genellina

>
> Hi Gabriel
>
> Are you sure about this? My understanding is that 'fileno' is just a
> FILE* cast to an integer. So it's a pointer to something (check out
> stdio.h to see what it points to). Problem is (AFAICT) that Python 2.4


A FILE struct usually *contains* a file descriptor, among other things.
But I think the FILE struct is opaque and not specified. Perhaps one
should go even at a lower level, using open_osfhandle and get_osfhandle.
(From python you can use the msvcrt module). See
http://msdn2.microsoft.com/en-us/lib...ay(VS.71).aspx
h=get_osfhandle(f.fileno()) returns a Windows file handle that you can
pass around.
On the Mingw side: fd=open_osfhandle(h); FILE *f=fdopen(fd)

> uses a different version of the C runtime DLL (MSVCRT*.DLL) to that
> which MinGW links against. And it turns out that the different C
> runtime libraries have incompatible implementations of the FILE
> struct. And therefore if you try to pass a FILE* (fileno?) from Python
> to MinGW you will get a segfault.


Exactly; the idea is not to pass a foreign FILE struct, but to *contruct*
another one based on an existing open file; this is what fdopen does.

> If there is more to your suggestion that I'm not seeing, please
> clarify. Have you tried this with MinGW actually?


No, but I'm rather confident it should work... as always, it can fail
miserably

--
Gabriel Genellina

 
Reply With Quote
 
John Pye
Guest
Posts: n/a
 
      03-21-2007
On Mar 21, 4:04 pm, Ross Ridge <(E-Mail Removed)>
wrote:
> Gabriel Genellina <(E-Mail Removed)> wrote:
> >You can get the file descriptor from the Python file object using its
> >fileno() method. The file descriptor lives at the OS level, so it's safe
> >to pass around.

>
> Not under Windows. Windows doesn't have Unix-like descriptors, so the
> C runtime emulates them.


I am trying the following... any thoughts?


%typemap(in) FILE * {
if (!PyFile_Check($input)) {
PyErr_SetString(PyExc_TypeError, "Need a file!");
return NULL;
}
%#ifdef __MINGW32__
PyFileObject *fo = (PyFileObject *)$input;
$1 = fdopen(_fileno(fo->f_fp),PyString_AsString(fo->f_mode));
fprintf(stderr,"FDOPEN(%d,\"%s\")\n",fo->f_fp,PyString_AsString(fo-
>f_mode));

%#else
$1 = PyFile_AsFile($input);
%#endif
}



 
Reply With Quote
 
Gabriel Genellina
Guest
Posts: n/a
 
      03-21-2007
En Wed, 21 Mar 2007 02:04:30 -0300, Ross Ridge
<(E-Mail Removed)> escribió:

> Gabriel Genellina <(E-Mail Removed)> wrote:


>> You can get the file descriptor from the Python file object using its
>> fileno() method. The file descriptor lives at the OS level, so it's safe
>> to pass around.

>
> Not under Windows. Windows doesn't have Unix-like descriptors, so the
> C runtime emulates them.


Using get_osfhandle on that pseudo-descriptor gives a Windows file handle;
that handle should be equivalent (that is, it has a similar role:
identifies an open file uniquely inside a process, and is independent on
the C runtime library)

--
Gabriel Genellina

 
Reply With Quote
 
John Pye
Guest
Posts: n/a
 
      03-21-2007
On Mar 21, 4:48 pm, "John Pye" <(E-Mail Removed)> wrote:
>
> I am trying the following... any thoughts?
>
> %typemap(in) FILE * {
> if (!PyFile_Check($input)) {
> PyErr_SetString(PyExc_TypeError, "Need a file!");
> return NULL;
> }
> %#ifdef __MINGW32__
> PyFileObject *fo = (PyFileObject *)$input;
> $1 = fdopen(_fileno(fo->f_fp),PyString_AsString(fo->f_mode));
> fprintf(stderr,"FDOPEN(%d,\"%s\")\n",fo->f_fp,PyString_AsString(fo->f_mode));
>
> %#else
> $1 = PyFile_AsFile($input);
> %#endif
>
> }



Ok, so this didn't work. 'fdopen' returned NULL. I guess that nails
the coffin for the fileno() approach?

Cheers
JP



 
Reply With Quote
 
Gabriel Genellina
Guest
Posts: n/a
 
      03-21-2007
En Wed, 21 Mar 2007 01:58:05 -0300, John Pye <(E-Mail Removed)> escribió:

> Hmm. Reading this again I think I understand properly now. The
> 'fileno' is really *not* the same thing as the FILE* pointer cast to
> an integer. It is a lower-level structure.

Just an integer. But as Ross Ridge has pointed out, it's not an OS thing
on Windows, it's faked by the C runtime.

> The question is now, if I don't want to modify my *python* code, how
> do I get at the 'fileno' property of my PyFileObject?


From Python, calling the fileno() method. From C, using
fileno(PyFile_AsFile(your_file_object))
And then, using get_osfhandle(fd)

> Also, are there consequences for using this approach of regenerating
> the FILE struct? For example if I have the following:
>
> F = os.tmpfile()
> F.write("some data")
> F.seek(0)
> myswigmodule.dosomething(F)
> F.seek(0)
> S = F.read()
> print S


Just try it and let us know what happens!

> I don't know enough about this low-level file handling to really
> understand the implications of what you are proposing -- perhaps you
> could explain a little?


It's too late (for me) now, but if you can't make it work I'll try an
example tomorrow.

--
Gabriel Genellina

 
Reply With Quote
 
John Pye
Guest
Posts: n/a
 
      03-21-2007
Gabriel, if you think you can make an example that works, that would
be great. I'm afraid I feel a bit out of my depth and don't have much
confidence in this idea.

JP

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
Re: [Swig-user] How to receive a FILE* from Python under MinGW? Carl Douglas Python 11 03-23-2007 01:48 AM
Re: [Swig-user] How to receive a FILE* from Python under MinGW? John Pye Python 0 03-21-2007 03:46 AM
[newbie]How to install python under DOS and is there any Wxpython can be installed under dos? john san Python 19 02-18-2005 12:05 PM
Re: JTable in Applet doesn't receive keypresses under Win2000 (XP is Ok) Dag Sunde Java 0 12-30-2004 04:16 PM



Advertisments