Hello!

I am wrapping an open source library with Cython. Hope to release some
code soon...

First of all, Cython works great for this! It took some time to get
used to, but soon it became fun to work on a C-Python border! :-)

And now the question.

The C library has structures that I'm wrapping with extension types.
Here's the code (simplified and without error handling):

cdef extern from "library.h":
    ctypedef struct lib_obj:
        int n

    int allocate_obj(lib_obj **obj)
    void deallocate_obj(lib_obj *obj)

cdef class Object(object):
    cdef lib_obj *obj

    def __cinit__(self, n):
        allocate_obj(&self.obj)
        self.obj.n = n

    def __dealloc__(self):
        if self.obj:
            deallocate_obj(self.obj)

Everything is nice so far. But then I had to wrap two more functions
from "library.h":

cdef extern from "library.h":
    ...
    # these functions transfer deallocation responsibility to the caller
    int copy_obj(lib_obj **dst, lib_obj *src)
    lib_obj *load_some_obj()

As you can see, I needed to create Object instances not only from
scratch, but reusing existing lib_obj pointer and skipping memory
allocation. Plus a nice copy_obj wrapper. After some trial-and-error
the code became:

cdef class Object(object):
    cdef lib_obj *obj

    def __cinit__(self, n=None, allocate=True):
        if allocate:
            allocate_obj(&self.obj)
            self.obj.n = n

    def __dealloc__(self):
        if self.obj:
            deallocate_obj(self.obj)

    def copy(self):
        cdef lib_obj *obj
        copy_obj(&obj, self.obj)
        o = Object(allocate=False)
        o.obj = obj
        return o

cdef Object wrap(lib_obj *obj):
    Object o
    o = Object(allocate=False)
    o.obj = obj
    return obj

def load_Object():
    cdef lib_obj *obj = load_some_obj()
    return wrap(obj)

Well, it works ;-) But can you suggest a nicer way to accomplish this? Problems:

1. Now I have to handle __cinit__ `allocate` argument in every
`Object` subclass. It's easy to forget about it -- I'm writing many
such subclasses.
2. Notice how I forgot to check for `n` value in __cinit__. One more
thing to forget...
3. I couldn't make `wrap` function a part of `Object` definition. I
tried to make it a cdef `fromobj` method decorated with @classmethod
or @staticmethod, but it didn't work.

Any suggestions? Or hidden problems?

Thanks!
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to