SWIG interfacing C library to Python (SWIG generated classes are cumbersome to use)
Question: I am using SWIG to generate Python language bindings to my C library. I have
managed to build the bindings and exported data structures, but I'm having to
jump through some hoops when using the library.

For example the C header has data types and function prototypes as follows:

    
    
    struct MyStruct
    {
        /* fields */
    } 
    
    struct MyStruct * MYSTRUCT_Alloc(void);
    void MYSTRUCT_Free(struct MyStruct *);
    struct MyStruct  * MYSTRUCT_Clone(const struct MyStruct *);
    int MYSTRUCT_Func1(const struct MyStruct *, const int);
    
    /* and so on */
    

In my SWIG interface file, I am exporting both the functions and the MyStruct
data type. Assuming my python extension module is called foobar, I can then
write Python script like this:

    
    
    #import foobar as fb
    
    # The line below creates a Python class which is a wrapper to MyStruct. HOWEVER I cannot pass this class to a function like MYSTRUCT_Func1 until I have initialized it by calling MYSTRUCT_Alloc ...
    
    ms = fb.MyStruct  
    
    # This will fail (throws a Python exception)
    # ret =  fb.MYSTRUCT_Func1(ms, 123)
    
    # However this works
    ms = fb.MYSTRUCT_Alloc()
    ret =  fb.MYSTRUCT_Func1(ms, 123)
    

It is very cumbersome (and error prone) to declare an object and then assign a
pointer to it before using it. Is there a better way of using the SWIG
generated classes?. I was thinking of wrapping higher level classes (or
subclassing the SWIG generated classes) to automagically take care of object
creation and destruction (as well as providing some OBVIOUS member functions
like MYSTRUCT_Func1().

HOWEVER, if I do wrap/subclass the SWIG generated classes, then I am not sure
that I can pass the new classes to the C API functions that expect a pointer
to a C struct. I can't modify the SWIG generated classes directly (or atleast
I shouldn't) - for OBVIOUS reasons.

What is the best way to solve this problem? A more pythonic way of
creating/destroying objects, whilst at the same time being able to pass
pointers directly to the exposed C functions?


Answer: Writing a wrapper on the Python side seems like a good idea to me, not sure
why you think that is not going to work.

    
    
    class MyStructWrapper:
        def __init__(self):
            self.ms = fb.MYSTRUCT_Alloc()
    
        def __del__(self):
            fb.MYSTRUCT_Free(self.ms)
    
        def func1(self, arg):
            return fb.MYSTRUCT_Func1(self.ms, arg)
    

And if you need to access the members of the struct, then you can do so with
`self.ms.member` or by writing getters and setters.

You can also fit your `clone` function into this design.

**Edit** : Regarding your comment, let's say you have a global function that
takes a pointer to `MyStruct`:

    
    
    int gFunc(MyStruct* ms);
    

In the Python side, you can write a wrapper as follows:

    
    
    def gFuncWrapper(mystruct):
        return fb.gFunc(mystruct.ms)
    

I hope this helps.

