Function References

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

    Function References

    Greetings,

    I'm trying to wrap a function in a C library as a compiled C Python
    module. Everything is going great, but I've hit a snag. There's a
    function in the form of this:

    First the typedef:
    typedef void(*FPtr_Devi ceMessageHandle r) (const DeviceMessage, const
    char*);

    Then the actual function prototype:
    FPtr_DeviceMess ageHandler
    RegisterDeviceM essageHandler(F Ptr_DeviceMessa geHandler);

    Whenever this USB device I'm using generates a message, it's then sent
    to that function whose reference you passed to
    RegisterDeviceM essageHandler() . Here's an example:

    void testfunc() {
    printf("test");
    }
    ....on to main()
    RegisterDeviceM essageHandler(& testfunc)

    So I've defined a similar function on my C module to do just this,
    using the passed function reference to allow the device to send
    messages to a Python function of the user's choice. I'm just not sure
    how to do this, and the tutorials I've been digging through don't
    offer any help. I've found some functions that look promising, but
    can't figure out how to cast the function reference from Python into
    something the C RegisterDevice. .. function can handle. Here's what
    I've got:

    static PyObject *
    Py1_RegisterDev iceMessageHandl er(PyObject *self, PyObject *args)
    {
    PyObject *handle, *parsed;

    if(!PyArg_Parse Tuple(args, "O", handle)) {
    return NULL;
    }

    parsed = PyMethod_Functi on(handle);
    I1_RegisterDevi ceMessageHandle r(PyMethod_Func tion(handle));

    Py_RETURN_TRUE;
    } // end Py1_RegisterDev iceMessageHandl er()

    This fails since PyMethod_Functi on returns a PyObject. Is there a way
    to cast this to something generic? Casting to (void*) didn't seem to
    work.

    Thanks in advance!
  • Diez B. Roggisch

    #2
    Re: Function References

    squishywaffle@g mail.com wrote:
    Greetings,
    >
    I'm trying to wrap a function in a C library as a compiled C Python
    module. Everything is going great, but I've hit a snag. There's a
    function in the form of this:
    >
    First the typedef:
    typedef void(*FPtr_Devi ceMessageHandle r) (const DeviceMessage, const
    char*);
    >
    Then the actual function prototype:
    FPtr_DeviceMess ageHandler
    RegisterDeviceM essageHandler(F Ptr_DeviceMessa geHandler);
    >
    Whenever this USB device I'm using generates a message, it's then sent
    to that function whose reference you passed to
    RegisterDeviceM essageHandler() . Here's an example:
    >
    void testfunc() {
    printf("test");
    }
    ...on to main()
    RegisterDeviceM essageHandler(& testfunc)
    >
    So I've defined a similar function on my C module to do just this,
    using the passed function reference to allow the device to send
    messages to a Python function of the user's choice. I'm just not sure
    how to do this, and the tutorials I've been digging through don't
    offer any help. I've found some functions that look promising, but
    can't figure out how to cast the function reference from Python into
    something the C RegisterDevice. .. function can handle. Here's what
    I've got:
    >
    static PyObject *
    Py1_RegisterDev iceMessageHandl er(PyObject *self, PyObject *args)
    {
    PyObject *handle, *parsed;
    >
    if(!PyArg_Parse Tuple(args, "O", handle)) {
    return NULL;
    }
    >
    parsed = PyMethod_Functi on(handle);
    I1_RegisterDevi ceMessageHandle r(PyMethod_Func tion(handle));
    >
    Py_RETURN_TRUE;
    } // end Py1_RegisterDev iceMessageHandl er()
    >
    This fails since PyMethod_Functi on returns a PyObject. Is there a way
    to cast this to something generic? Casting to (void*) didn't seem to
    work.
    >
    Thanks in advance!
    May I suggest you move to ctypes for wrapping? It's easier, pure python and
    callbacks are already built-in.

    Diez

    Comment

    • squishywaffle@gmail.com

      #3
      Re: Function References

      Hello Diez.
      May I suggest you move to ctypes for wrapping? It's easier, pure python and
      callbacks are already built-in.
      I'm pretty new to extending Python in C, I don't understand what
      you're saying. Are there any examples or a brief explanation/URL you
      could point me to?

      Comment

      • Diez B. Roggisch

        #4
        Re: Function References

        squishywaffle@g mail.com wrote:
        Hello Diez.
        >
        >May I suggest you move to ctypes for wrapping? It's easier, pure python
        >and callbacks are already built-in.
        >
        I'm pretty new to extending Python in C, I don't understand what
        you're saying. Are there any examples or a brief explanation/URL you
        could point me to?
        Is google dead today?



        First hit.

        Ctypes is a since python2.5 built-in module that allows to declare
        interfaces to C-libraries in pure python. You declare datatypes and
        function prototypes, load a DLL/SO and then happily work with it. No C, no
        compiler, no refcounts, no nothing.

        And you can pass python-functions as callbacks.

        See the module docs for examples.

        Diez

        Comment

        • squishywaffle@gmail.com

          #5
          Re: Function References

          Ctypes is a since python2.5 built-in module that allows to declare
          interfaces to C-libraries in pure python. You declare datatypes and
          function prototypes, load a DLL/SO and then happily work with it. No C, no
          compiler, no refcounts, no nothing.
          >
          And you can pass python-functions as callbacks.
          The first sentence (and some really crummy licensing restrictions
          imposed by the library distributor) alone here excludes this as a
          valid option for this particular case, I definitely need Python 2.4
          support.

          So the question comes back around to being how is this same desired
          behavior duplicated in the Python/C API?

          Comment

          • Diez B. Roggisch

            #6
            Re: Function References

            squishywaffle@g mail.com wrote:
            >Ctypes is a since python2.5 built-in module that allows to declare
            >interfaces to C-libraries in pure python. You declare datatypes and
            >function prototypes, load a DLL/SO and then happily work with it. No C,
            >no compiler, no refcounts, no nothing.
            >>
            >And you can pass python-functions as callbacks.
            >
            The first sentence (and some really crummy licensing restrictions
            imposed by the library distributor) alone here excludes this as a
            valid option for this particular case, I definitely need Python 2.4
            support.
            How much more liberal can it get than MIT-licensed?

            """
            to deal in the Software without restriction, including
            without limitation the rights to use, copy, modify, merge, publish,
            distribute, sublicense, and/or sell copies of the Software, and to
            permit persons to whom the Software is furnished to do so, subject to
            the following conditions:
            """

            But then, if you insist, go down the hard road.

            Diez

            Comment

            • Diez B. Roggisch

              #7
              Re: Function References

              Diez B. Roggisch wrote:
              squishywaffle@g mail.com wrote:
              >
              >>Ctypes is a since python2.5 built-in module that allows to declare
              >>interfaces to C-libraries in pure python. You declare datatypes and
              >>function prototypes, load a DLL/SO and then happily work with it. No C,
              >>no compiler, no refcounts, no nothing.
              >>>
              >>And you can pass python-functions as callbacks.
              >>
              >The first sentence (and some really crummy licensing restrictions
              >imposed by the library distributor) alone here excludes this as a
              >valid option for this particular case, I definitely need Python 2.4
              >support.
              >
              How much more liberal can it get than MIT-licensed?
              >
              """
              to deal in the Software without restriction, including
              without limitation the rights to use, copy, modify, merge, publish,
              distribute, sublicense, and/or sell copies of the Software, and to
              permit persons to whom the Software is furnished to do so, subject to
              the following conditions:
              """
              Sorry, missed the paragraph

              """
              The above copyright notice and this permission notice shall be
              included in all copies or substantial portions of the Software.
              """

              Still, AFAIK MIT is pretty liberal.

              Diez

              Comment

              • squishywaffle@gmail.com

                #8
                Re: Function References

                How much more liberal can it get than MIT-licensed?

                Again, the licensing issue is everything to do with the original
                library distributor, NOT ctypes.
                But then, if you insist, go down the hard road.
                Irrelevant and unnecessary. If you don't want to help, don't please
                don't reply.

                Comment

                • Diez B. Roggisch

                  #9
                  Re: Function References

                  squishywaffle@g mail.com wrote:
                  >How much more liberal can it get than MIT-licensed?
                  >
                  Again, the licensing issue is everything to do with the original
                  library distributor, NOT ctypes.
                  I read library distributor as "ctypes-library distributor" because it is
                  3rd-party under 2.4. Which was the reason I quotet it's MIT-license.

                  And it escapes me what accessing the lib from ctypes is any different than
                  from your own compiled code.
                  >But then, if you insist, go down the hard road.
                  >
                  Irrelevant and unnecessary. If you don't want to help, don't please
                  don't reply.
                  I take the freedom to do so as I see fit - this is usenet...

                  Diez

                  Comment

                  • squishywaffle@gmail.com

                    #10
                    Re: Function References

                    On Jul 31, 10:47 am, "Diez B. Roggisch" <de...@nospam.w eb.dewrote:
                    I take the freedom to do so as I see fit - this is usenet...
                    Fine, then keep beating a dead horse by replying to this thread with
                    things that do nobody any good. It seems like there are a lot better
                    way to waste time, though.

                    The Python/C API can get me back further without reliance on third-
                    party libraries than ctypes. It also isn't subject to the quirks that
                    ctypes is on platforms other than Windows (the target application runs
                    on Windows, Mac, and eventually Linux once the original distributor
                    has drivers for the device). I'm not even sure ctypes could load the
                    lib/driver the distributor packaged.

                    So really, I appreciate the option in ctypes, it's good stuff. But
                    it's not for this project.

                    Once again, the original question stands for anyone who has experience
                    with the Python/C API callbacks.

                    Comment

                    • Matthew Woodcraft

                      #11
                      Re: Function References

                      >Ctypes is a since python2.5 built-in module that allows to declare
                      >interfaces to C-libraries in pure python. You declare datatypes and
                      >function prototypes, load a DLL/SO and then happily work with it. No C, no
                      >compiler, no refcounts, no nothing.
                      >>
                      >And you can pass python-functions as callbacks.
                      squishywaffle@g mail.com wrote:
                      The first sentence (and some really crummy licensing restrictions
                      imposed by the library distributor) alone here excludes this as a
                      valid option for this particular case, I definitely need Python 2.4
                      support.
                      Perhaps all is not lost: ctypes works from Python 2.3 up. That first
                      sentence is saying that since Python 2.5 it has been included in the
                      standard Python distribution, but you can still download it separately.

                      -M-

                      Comment

                      • Carsten Haese

                        #12
                        Re: Function References

                        squishywaffle@g mail.com wrote:
                        Greetings,
                        >
                        I'm trying to wrap a function in a C library as a compiled C Python
                        module. Everything is going great, but I've hit a snag. There's a
                        function in the form of this:
                        >
                        First the typedef:
                        typedef void(*FPtr_Devi ceMessageHandle r) (const DeviceMessage, const
                        char*);
                        >
                        Then the actual function prototype:
                        FPtr_DeviceMess ageHandler
                        RegisterDeviceM essageHandler(F Ptr_DeviceMessa geHandler);
                        [...]
                        [I] can't figure out how to cast the function reference from Python into
                        something the C RegisterDevice. .. function can handle.
                        Mere casting won't do the trick. The function reference from Python is
                        basically just an object that contains byte-code to be executed by the
                        Python Virtual Machine. There is no way you can magically transform that
                        into a C function by casting the Python object pointer to anything.

                        You'll need a write a C function that will call a given Python function,
                        and then you need to supply the pointer to that C function as your
                        DeviceMessageHa ndler callback function, and somehow communicate to your
                        C function which Python function it should call.

                        Good luck.

                        --
                        Carsten Haese

                        Comment

                        • Diez B. Roggisch

                          #13
                          Re: Function References

                          squishywaffle@g mail.com schrieb:
                          On Jul 31, 10:47 am, "Diez B. Roggisch" <de...@nospam.w eb.dewrote:
                          >I take the freedom to do so as I see fit - this is usenet...
                          >
                          Fine, then keep beating a dead horse by replying to this thread with
                          things that do nobody any good. It seems like there are a lot better
                          way to waste time, though.
                          You mean like trying to wrap ones head around the rather simple Python C
                          API, not getting a callback mechanism implemented?

                          For the record: I've wrapped C-libs myself, including callbacks. Been
                          there, done that, discovered (years later) cytpes, been there for good.
                          The Python/C API can get me back further without reliance on third-
                          party libraries than ctypes.
                          You don't consider your own library a third party lib? And unless you're
                          wrapping C++, you're opinion is as uninformed as it is wrong.
                          It also isn't subject to the quirks that
                          ctypes is on platforms other than Windows (the target application runs
                          on Windows, Mac, and eventually Linux once the original distributor
                          has drivers for the device). I'm not even sure ctypes could load the
                          lib/driver the distributor packaged.
                          Oh please. I'm 98% working on linux & osx. ctypes does a great job on
                          these platforms.

                          Regarding your objections I can only say: whatever the python runtime
                          can load because of the underlying ld, ctypes can load. simply because
                          they are the same. If *that* was the actual cause of problems, we
                          wouldn't even talk about callbacks here.
                          So really, I appreciate the option in ctypes, it's good stuff. But
                          it's not for this project.
                          Stop finding lame excuses for not wanting to ditch the work you've done
                          in favor of a easier solution. You like your code, you want to keep it,
                          you want to discover the intricasies of the Python C API? Be my guest.

                          But stop embarassing yourself inventing reasons like licensing or linker
                          problems you don't support with any facts whatsoever.
                          Once again, the original question stands for anyone who has experience
                          with the Python/C API callbacks.
                          You know what? Just for the fun of it, I'll take a stab at it.

                          It's easy: Create a "proxy-function" that matches the prototype of the
                          c8allback which converts the passed arguments to python values using the
                          C-api. Then call the registered python function using
                          PyObject_CallFu nction.

                          Convert the return-value back to C, and return it.

                          Make the function get the PyObject* for the call fetch from a global
                          variable you set in the register-callback function, where you also
                          register the proxy-function for the first time, or de-register if the
                          passed value is None or such.

                          Have fun.


                          Diez

                          Comment

                          • Lie

                            #14
                            Re: Function References

                            On Aug 1, 6:35 am, "Diez B. Roggisch" <de...@nospam.w eb.dewrote:
                            squishywaf...@g mail.com schrieb:
                            >
                            On Jul 31, 10:47 am, "Diez B. Roggisch" <de...@nospam.w eb.dewrote:
                            I take the freedom to do so as I see fit - this is usenet...
                            >
                            Fine, then keep beating a dead horse by replying to this thread with
                            things that do nobody any good. It seems like there are a lot better
                            way to waste time, though.
                            >
                            You mean like trying to wrap ones head around the rather simple Python C
                            API, not getting a callback mechanism implemented?
                            >
                            For the record: I've wrapped C-libs myself, including callbacks. Been
                            there, done that, discovered (years later) cytpes, been there for good.
                            >
                            The Python/C API can get me back further without reliance on third-
                            party libraries than ctypes.
                            >
                            You don't consider your own library a third party lib? And unless you're
                            wrapping C++, you're opinion is as uninformed as it is wrong.
                            >
                            It also isn't subject to the quirks that
                            ctypes is on platforms other than Windows (the target application runs
                            on Windows, Mac, and eventually Linux once the original distributor
                            has drivers for the device). I'm not even sure ctypes could load the
                            lib/driver the distributor packaged.
                            >
                            Oh please. I'm 98% working on linux & osx. ctypes does a great job on
                            these platforms.
                            >
                            Regarding your objections I can only say: whatever the python runtime
                            can load because of the underlying ld, ctypes can load. simply because
                            they are the same. If *that* was the actual cause of problems, we
                            wouldn't even talk about callbacks here.
                            >
                            So really, I appreciate the option in ctypes, it's good stuff. But
                            it's not for this project.
                            >
                            Stop finding lame excuses for not wanting to ditch the work you've done
                            in favor of a easier solution. You like your code, you want to keep it,
                            you want to discover the intricasies of the Python C API? Be my guest.
                            >
                            But stop embarassing yourself inventing reasons like licensing or linker
                            problems you don't support with any facts whatsoever.
                            >
                            Once again, the original question stands for anyone who has experience
                            with the Python/C API callbacks.
                            >
                            You know what? Just for the fun of it, I'll take a stab at it.
                            >
                              It's easy: Create a "proxy-function" that matches the prototype of the
                            c8allback which converts the passed arguments to python values using the
                            C-api. Then call the registered python function using
                            PyObject_CallFu nction.
                            >
                            Convert the return-value back to C, and return it.
                            >
                            Make the function get the PyObject* for the call fetch from a global
                            variable you set in the register-callback function, where you also
                            register the proxy-function for the first time, or de-register if the
                            passed value is None or such.
                            >
                            Have fun.
                            >
                            Diez
                            Zen's lesson for today:
                            THOU SHALT NOT MESS WITH ANY PYTHON'S SEMI-GODS, DEMI-GODS, AND
                            PYTHON'S GOD.

                            You're lucky Diez still want to help you with your attitude like that.
                            May I remind you that we here helps you for free in our free time, be
                            rude, especially to a frequent member, and you'll get what you deserve.

                            Comment

                            • Diez B. Roggisch

                              #15
                              Re: Function References

                              Zen's lesson for today:
                              THOU SHALT NOT MESS WITH ANY PYTHON'S SEMI-GODS, DEMI-GODS, AND
                              PYTHON'S GOD.
                              >
                              You're lucky Diez still want to help you with your attitude like that.
                              May I remind you that we here helps you for free in our free time, be
                              rude, especially to a frequent member, and you'll get what you deserve.
                              Thanks Lie, but I certainly don't consider myself being part of Python's
                              olymp... :) Others here of course are, and a friendly and open attitude
                              from everybody sure helps keeping this institution helpful.

                              This goes also for frequent members - and I do include myself here, as I
                              *sometimes* forget that myself, but try hard not to.

                              Diez

                              Comment

                              Working...