tags:

views:

291

answers:

2

Hi! I am trying to call a C function sitting in a shared object from python, and using ctypes seems to be the best way of accomplishing this. I have to pass derived types to this function, with the following function prototype:

int MyFunc (Config *config, int *argc, char **argv )

The Config struct is defined as

 typedef struct{ char *some_filename ;
                 char **some_other_filenames ;
                 int some_value ;
                 Coord resolution;
               } Config;

Coord is defined as

 typdef struct { double x, y, area }  Coord ;

The python ctypes code is then just a re-write of the derived types:

 class COORD ( ctypes.Structure ):
       _fields = [ ("lon",ctypes.c_double),\
       ("lat", ctypes.c_double),\
       ("area", ctypes.c_double)]
 coords = COORD()
 class CONFIG( ctypes.Structure ):
       _fields = [ ("some_filename", ctypes.c_char_p),\
       ("some_other_filenames", ctypes.c_char_p('\0' * 256)),\
       ("some_value", ctypes.c_int ),\
       ("resolution", coords )   ]

I then set up the arguments for MyFunc:

 MyFunc.argtypes = [ctypes.byref(CONFIG ) , ctypes.POINTER(ctypes.c_int),\
  ctypes.POINTER (ctypes.c_char_p)]
 MyFunc.restype = ctypes.c_int 
 myargv = ctypes.c_char_p * 2
 argv = myargv("One", "Two")
 argc = ctypes.c_int ( 2 )
 retval = MyFunc (  ctypes.byref(config), ctypes.byref(argc), ctypes(argv))

This, however, produces a segfault. Anyone have any ideas what's going on in here?

UPDATE There was a typo in my question, from cutting and pasting, problem is still there!

+1  A: 

It doesn't look like your rewritten config structure is the same as the original one. If you're passing it back and forth the alignment would be off.

Edit: I see you've fixed part of it. But I'm not sure that c_char_p is the same as char**.

John D.
You are right, the integer member was missing. I have edited it now, but this was just me having trouble cutting and pasting! Thanks!
Jose
A: 

char** corresponds to POINTER(c_char_p), not to c_char_p.

Nikratio