1

I am trying to make a python wrapper for a C library using ctypes. The library has functions which require a pointer to a structure to be passed, which acts as a handle for future calls.

This structure has pointers to another internal structure that further has pointers to other structures.

typedef struct varnam { char *scheme_file; char *suggestions_file; struct varnam_internal *internal; } varnam; 

The varnam_internal structure has pointers to an sqlite database and so forth

struct varnam_internal { sqlite3 *db; sqlite3 *known_words; struct varray_t *r; struct token *v; ... } 

I tried ignoring the varnam_internal structure according to this SO answer. Something like

class Varnam(Structure): __fields__ = [("scheme_file",c_char_p), ("suggestions_file",c_char_p),("internal",c_void_p)] 

But this does not seem to work because I think the library needs to allocate varnam_internal for functioning properly.

Should I implement all the dependent structures in python? Is ctypes suitable for wrapping libraries like this? I have read about alternatives like Cython but I have no experience with Cython so is this doable in it?

1 Answer 1

1

There's no reason define the varnam_internal structure in ctypes because you should have no need to access it. The library you're calling will allocate it regardless of whether you define the structure or not. Whatever problem you're encountering it's not because you didn't define the structure in ctypes.

Make sure you're calling varnam_init correctly. It uses pointers to pointers as arguments, which means you can't just use your Varnam class directly. You'll want do something like this:

from ctypes import * class Varnam(Structure): __fields__ = [("scheme_file",c_char_p), ("suggestions_file",c_char_p), ("internal",c_void_p)] varnam_ptr = POINTER(Varnam) libvarnam = cdll.LoadLibrary("libvarnam.so") # on Linux # libvarnam = cdll.libvarnam # on Windows varnam_init = libvarnam.varnam_init varnam_init.argtypes = [c_char_p, POINTER(varnam_ptr), POINTER(c_char_p)] def my_varnam_init(scheme_file): handle = varnam_ptr() msg = c_char_p() r = varnam_init(scheme_file. handle.byref(), msg.byref()) if r != 0: raise Exception(msg) return handle 

The above code is completely untested, but shows you how you should be calling varnam_init.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. You're right, I created a pointer of the Varnam class and used that for the function and not a pointer to a pointer. Now it works flawlessly.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.