C Module question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • boblatest@googlemail.com

    C Module question

    Hello,

    I'm trying to write a Python extension module in C for the first time.
    I have two questions:

    1. How can I pass a file-like object into the C part? The PyArg_*
    functions can convert objects to all sort of types, but not FILE*.

    2. How can I preserve information needed in the C part between calls
    to my module functions? The way I've thought of is:
    - put this information in a dynamically allocated struct
    - pass it out of and into the C module as CObject into/from an
    intermediate Python wrapper module where it gets stored in a Python
    object

    Is this the way to do it?

    Thanks.
    robert
  • Christian Heimes

    #2
    Re: C Module question

    boblatest@googl email.com wrote:
    Hello,
    >
    I'm trying to write a Python extension module in C for the first time.
    I have two questions:
    I have a much better suggestion:

    Use Cython!

    Although I'm pretty experienced with the Python C API, I prefer Cython
    over hand written C code for most stuff. It's so much easier to write a
    wrapper in Cython than by hand.

    Christian

    Comment

    • Marc 'BlackJack' Rintsch

      #3
      Re: C Module question

      On Mon, 10 Nov 2008 03:11:06 -0800, boblatest@googl email.com wrote:
      1. How can I pass a file-like object into the C part? The PyArg_*
      functions can convert objects to all sort of types, but not FILE*.
      These APIs are a minimal emulation of the Python 2 C API for built-in file objects, which used to rely on the buffered I/O ( FILE*) support from the C standard library. In Python 3, files and strea...

      2. How can I preserve information needed in the C part between calls to
      my module functions? The way I've thought of is: - put this information
      in a dynamically allocated struct - pass it out of and into the C module
      as CObject into/from an intermediate Python wrapper module where it gets
      stored in a Python object
      Why passing it in and out? Simply use the C module level to store the
      information.

      Ciao,
      Marc 'BlackJack' Rintsch

      Comment

      • Floris Bruynooghe

        #4
        Re: C Module question

        Hi

        On Nov 10, 11:11 am, "boblat...@goog lemail.com"
        <boblat...@goog lemail.comwrote :
        1. How can I pass a file-like object into the C part? The PyArg_*
        functions can convert objects to all sort of types, but not FILE*.
        Parse it as a generic PyObject object (format string of "O" in
        PyArg_*), check the type and cast it. Or use "O!" as format string
        and the typechecking can be done for you, only thing left is casting
        it.

        See http://docs.python.org/c-api/arg.html and http://docs.python.org/c-api/file.html
        for exact details.

        (2 is answered already...)

        Regards
        Floris

        Comment

        • Floris Bruynooghe

          #5
          Re: C Module question

          On Nov 10, 1:18 pm, Floris Bruynooghe <floris.bruynoo ...@gmail.com>
          wrote:
          On Nov 10, 11:11 am, "boblat...@goog lemail.com"
          >
          <boblat...@goog lemail.comwrote :
          1. How can I pass a file-like object into the C part? The PyArg_*
          functions can convert objects to all sort of types, but not FILE*.
          >
          Parse it as a generic PyObject object (format string of "O" in
          PyArg_*), check the type and cast it.  Or use "O!" as format string
          and the typechecking can be done for you, only thing left is casting
          it.
          >
          Seehttp://docs.python.org/c-api/arg.htmlandhttp ://docs.python.org/c-api/file.html
          for exact details.
          Sorry, I probably should have mentioned you want to cast the object to
          PyFileObject and then use the PyFile_AsFile() function to get the
          FILE* handle.


          Floris

          Comment

          • boblatest@googlemail.com

            #6
            Re: C Module question

            On Nov 10, 1:16 pm, Marc 'BlackJack' Rintsch <bj_...@gmx.net wrote:
            On Mon, 10 Nov 2008 03:11:06 -0800, boblat...@googl email.com wrote:
            1. How can I pass a file-like object into the C part? The PyArg_*
            functions can convert objects to all sort of types, but not FILE*.
            >
            http://docs.python.org/c-api/file.html#PyFile_AsFile
            Yes, got it. At first I thought I had to use the "Parse" functions for
            my args, but in fact I can of course just access the args as a tuple
            (and then do the type checking myself).
            Why passing it in and out?  Simply use the C module level to store the
            information.
            But if I create several instances of a class (in the wrapper module)
            my C methods won't know which object they were called on.

            robert

            Comment

            • boblatest@googlemail.com

              #7
              Re: C Module question

              On Nov 10, 2:23 pm, Floris Bruynooghe <floris.bruynoo ...@gmail.com>
              wrote:
              Sorry, I probably should have mentioned you want to cast the object to
              PyFileObject and then use the PyFile_AsFile() function to get the
              FILE* handle.
              Yes, I figured that out by now. Sadly this doesn't work on "file-like"
              objects like those that are created by opening bz2 files (using the
              bz2 lib). Not that I have any idea on how that should work anyway.

              I still can resolve this issue in my wrapper module and let the C part
              deal with the raw buffer contents.

              All in all I must say that implementing a C extension is a piece of
              cake. Had I known that it was this straightforward I wouldn't have
              asked my questions in the first place. Making the whole thing more
              robust will be a bit more difficult, and I need to find out how to
              deal with ressources that are dynamically allocated on the C side.

              But that should be easy, and I'll just keep all the Python OO and
              Exceptions stuff in the wrapper and call my C stuff from there in a
              more or less straightforward C manner.

              Thanks to everybody for helping out,

              robert
              (I'll be back for sure)

              Comment

              • Marc 'BlackJack' Rintsch

                #8
                Re: C Module question

                On Mon, 10 Nov 2008 05:36:58 -0800, boblatest@googl email.com wrote:
                On Nov 10, 1:16 pm, Marc 'BlackJack' Rintsch <bj_...@gmx.net wrote:
                >On Mon, 10 Nov 2008 03:11:06 -0800, boblat...@googl email.com wrote:
                1. How can I pass a file-like object into the C part? The PyArg_*
                functions can convert objects to all sort of types, but not FILE*.
                >>
                >http://docs.python.org/c-api/file.html#PyFile_AsFile
                >
                Yes, got it. At first I thought I had to use the "Parse" functions for
                my args, but in fact I can of course just access the args as a tuple
                (and then do the type checking myself).
                >
                >Why passing it in and out?  Simply use the C module level to store the
                >information.
                >
                But if I create several instances of a class (in the wrapper module) my
                C methods won't know which object they were called on.
                Well you talked about functions in the module not about methods on
                objects.

                Ciao,
                Marc 'BlackJack' Rintsch

                Comment

                • Marc 'BlackJack' Rintsch

                  #9
                  Re: C Module question

                  On Mon, 10 Nov 2008 05:44:44 -0800, boblatest@googl email.com wrote:
                  All in all I must say that implementing a C extension is a piece of
                  cake. Had I known that it was this straightforward I wouldn't have asked
                  my questions in the first place. Making the whole thing more robust will
                  be a bit more difficult, and I need to find out how to deal with
                  ressources that are dynamically allocated on the C side.
                  >
                  But that should be easy, and I'll just keep all the Python OO and
                  Exceptions stuff in the wrapper and call my C stuff from there in a more
                  or less straightforward C manner.
                  Then you might considering the `ctypes` module to call your C stuff.
                  This way it is easier to build the extension and it is also independent
                  from the Python version.

                  Ciao,
                  Marc 'BlackJack' Rintsch

                  Comment

                  • John Machin

                    #10
                    Re: C Module question

                    On Nov 11, 12:55 am, Marc 'BlackJack' Rintsch <bj_...@gmx.net wrote:
                    On Mon, 10 Nov 2008 05:44:44 -0800, boblat...@googl email.com wrote:
                    All in all I must say that implementing a C extension is a piece of
                    cake. Had I known that it was this straightforward I wouldn't have asked
                    my questions in the first place. Making the whole thing more robust will
                    be a bit more difficult
                    Forget "more robust". You need "quite robust". Seriously consider
                    abandoning your "piece of cake" euphoria and use Cython or ctypes
                    instead. At the very least check out the C code that Cython generates
                    for a simple task and consider whether you really want to hand-code
                    that.

                    Comment

                    • greg

                      #11
                      Re: C Module question

                      boblatest@googl email.com wrote:
                      Sadly this doesn't work on "file-like"
                      objects like those that are created by opening bz2 files (using the
                      bz2 lib).
                      If the C code you're calling requires a FILE *, then you're
                      out of luck. There's no way of getting a FILE * from an object
                      that's not based on an actual PyFile object, since there
                      simply isn't one to be had.

                      There is an exception to that -- if the object is one that
                      has a file descriptor underlying it somewhere (such as a
                      pipe or socket) you could get that and wrap it using fdopen().

                      --
                      Greg

                      Comment

                      • Gabriel Genellina

                        #12
                        Re: C Module question

                        En Mon, 10 Nov 2008 11:44:44 -0200, boblatest@googl email.com
                        <boblatest@goog lemail.comescri bió:
                        On Nov 10, 2:23 pm, Floris Bruynooghe <floris.bruynoo ...@gmail.com>
                        wrote:
                        >
                        >Sorry, I probably should have mentioned you want to cast the object to
                        >PyFileObject and then use the PyFile_AsFile() function to get the
                        >FILE* handle.
                        >
                        Yes, I figured that out by now. Sadly this doesn't work on "file-like"
                        objects like those that are created by opening bz2 files (using the
                        bz2 lib). Not that I have any idea on how that should work anyway.
                        Call the file-like methods as you would with any other object method. That
                        is, if you got an object `fobj` from Python and you want to write a C
                        string:

                        char* str="some text\n";
                        PyObject_CallMe thod(fobj, "write", "s", str)

                        See also PyObject_CallOb ject and the other variants:


                        --
                        Gabriel Genellina

                        Comment

                        Working...