ctypes and setjmp

Discussion in 'Python' started by Richard Jones, Oct 6, 2006.

  1. Currently ctypes can't play well with any C code that requires use of setjmp
    as part of its API.

    libpng is one of those libraries.

    Can anyone think of a reasonable solution to this? Perhaps ctypes might be
    patched to offer setjmp support in foreign function definitions?


    Richard
    Richard Jones, Oct 6, 2006
    #1
    1. Advertising

  2. Richard Jones schrieb:
    > Currently ctypes can't play well with any C code that requires use of setjmp
    > as part of its API.
    >
    > libpng is one of those libraries.
    >
    > Can anyone think of a reasonable solution to this? Perhaps ctypes might be
    > patched to offer setjmp support in foreign function definitions?
    >
    >
    > Richard
    >

    I didn't know that setjmp/longjmp is actually used by production libraries
    for error handling.

    How is this pattern used in C? Do you call setjump() before each api call,
    or do you call setjump once, and then do all the api calls? What do you do
    when setjmp() returns != 0? Exit the program? Log a message? How do you
    determine which call failed? How do you pass the jmp_buf that you passed to
    setjmp() to the api call?

    For ctypes, the only solution I can think of is to invent a new calling
    convention, which will call setjmp() first internally before calling the
    libpng api function...

    Thomas
    Thomas Heller, Oct 6, 2006
    #2
    1. Advertising

  3. Thomas Heller wrote:

    > Richard Jones schrieb:
    >> Currently ctypes can't play well with any C code that requires use of
    >> setjmp as part of its API.
    >>
    >> libpng is one of those libraries.
    >>
    >> Can anyone think of a reasonable solution to this? Perhaps ctypes might
    >> be patched to offer setjmp support in foreign function definitions?
    >>
    >>
    >> Richard
    >>

    > I didn't know that setjmp/longjmp is actually used by production libraries
    > for error handling.


    To be honest, I didn't even know what setjmp/longjmp *were* until I hit its
    use in libpng, and I've been programming C for over a decade now ;)

    > How is this pattern used in C? Do you call setjump() before each api
    > call, or do you call setjump once, and then do all the api calls?


    I believe you call setjmp just before calling the API function in question.


    > What do you do when setjmp() returns != 0?


    I'd say that in ctypes land you'd have to provide a function to call in that
    situation. ctypes would call that function and then continue on. It's up to
    that function to raise an exception or otherwise flag the error. So in
    rough terms, you'd have ctypes do:

    if (error_handler != NULL) r = 0;
    else r = setjmp();
    if (r == 0) api_call();
    if (r == 1) error_handler();


    > For ctypes, the only solution I can think of is to invent a new calling
    > convention, which will call setjmp() first internally before calling the
    > libpng api function...


    Yeah, that's what I figured.


    Richard
    Richard Jones, Oct 7, 2006
    #3
  4. At Friday 6/10/2006 16:14, Thomas Heller wrote:

    > > Currently ctypes can't play well with any C code that requires

    > use of setjmp
    > > as part of its API.
    > > libpng is one of those libraries.
    > >

    >I didn't know that setjmp/longjmp is actually used by production libraries
    >for error handling.


    Using setjmp to report errors in a general library is, uhm, a bit
    crazy at least!
    C programmers are certainly crazy people :)

    >How is this pattern used in C? Do you call setjump() before each api call,
    >or do you call setjump once, and then do all the api calls? What do you do
    >when setjmp() returns != 0? Exit the program? Log a message? How do you
    >determine which call failed? How do you pass the jmp_buf that you passed to
    >setjmp() to the api call?


    The setjmp must be on scope when a longjmp is called. Since there is
    no endjmp/canceljmp, this in the practice means that you have to call
    setjmp in *every* function that calls another one which may issue a longjmp.
    There are other alternatives in plain C (cexcept:
    http://cexcept.sourceforge.net/) but that wont help you with ctypes.

    >For ctypes, the only solution I can think of is to invent a new calling
    >convention, which will call setjmp() first internally before calling the
    >libpng api function...


    May be reasonable - a non-zero in setjmp would raise a Python
    exception. But perhaps a new calling convention is not needed: as you
    need a way to indicate *which* argument is the jmp_buf, just a new
    argument type would suffice. If you encounter one such thing in the
    function.argtypes list, that means a setjmp is needed before calling
    the actual function.



    Gabriel Genellina
    Softlab SRL





    __________________________________________________
    Preguntá. Respondé. Descubrí.
    Todo lo que querías saber, y lo que ni imaginabas,
    está en Yahoo! Respuestas (Beta).
    ¡Probalo ya!
    http://www.yahoo.com.ar/respuestas
    Gabriel Genellina, Oct 7, 2006
    #4
  5. Gabriel Genellina wrote:
    > At Friday 6/10/2006 16:14, Thomas Heller wrote:
    >>For ctypes, the only solution I can think of is to invent a new calling
    >>convention, which will call setjmp() first internally before calling the
    >>libpng api function...

    >
    > May be reasonable - a non-zero in setjmp would raise a Python
    > exception. But perhaps a new calling convention is not needed: as you
    > need a way to indicate *which* argument is the jmp_buf, just a new
    > argument type would suffice. If you encounter one such thing in the
    > function.argtypes list, that means a setjmp is needed before calling
    > the actual function.


    The ctypes C code which handles invoking the foreign function call must be
    responsible for calling setjmp(). You can't call that in Python code - the
    C stack is manipulated all over the place for each line of Python code
    executed. You have to both call and set the jmp_buf in the same C code call
    from Python.

    Thus my suggestion of configuring a handler function on the foreign function
    wrapper object alongside the argtypes and restype. If one is defined then
    ctypes automatically calls setjmp and passes control to that handler
    function if setjmp returns non-zero.

    This page:

    http://www.massey.ac.nz/~mgwalker/misc/create-images.html

    has some example programs that show setjmp/longjmp in action. Read the whole
    thing as his first examples aren't correct :)


    Richard
    Richard Jones, Oct 7, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Henk Punt
    Replies:
    0
    Views:
    390
    Henk Punt
    Jul 23, 2004
  2. Merrill & Michele

    setjmp.h and other people's implementations

    Merrill & Michele, Oct 2, 2004, in forum: C Programming
    Replies:
    2
    Views:
    292
    Merrill & Michele
    Oct 2, 2004
  3. Zheng Da
    Replies:
    8
    Views:
    485
    Christian Bau
    Nov 7, 2005
  4. Sreekanth

    Problem with setjmp and long jump

    Sreekanth, Feb 15, 2006, in forum: C Programming
    Replies:
    4
    Views:
    329
    Chris Torek
    Feb 15, 2006
  5. Replies:
    0
    Views:
    495
Loading...

Share This Page