J
jamadagni
Hello. I am running Kubuntu Raring with Python 3.3.1. (I mostly don't myself use Py2.)
I have the below C program spiro.c (obviously a simplified testcase) which I compile to a sharedlib using clang -fPIC -shared -o libspiro.so spiro.c, sudo cp to /usr/lib and am trying to call from a Python script spiro.py using ctypes. However it would seem that the first call to the callback results in a segfault. (The line before the callback is executed.) I tried debugging using gdb but perhaps because of my insufficient knowledge I couldn't find out what is causing the problem.
I hope some of the kind knowledgeable souls here can help me out:
-- spiro.c
# include <stdbool.h>
# include <stdio.h>
typedef struct _bezctx bezctx ;
struct _bezctx {
void ( * moveto ) ( bezctx * bc, double x, double y, bool starts_open_path ) ;
void ( * lineto ) ( bezctx * bc, double x, double y ) ;
void ( * curveto ) ( bezctx * bc, double c1x, double c1y, double c2x, double c2y, double x, double y ) ;
void ( * track_seg ) ( bezctx * bc, unsigned int start_node_idx ) ;
} ;
typedef struct {
double x, y ;
char ty ;
} spiro_cp ;
bool spiro_to_bezier_strict ( const spiro_cp src [], int src_len, bezctx * bc ) {
for ( int i = 0 ; i < src_len ; ++i ) {
const spiro_cp * p = &(src) ;
printf ( "%g %g %c\n", p->x, p->y, p->ty ) ;
if ( i % 2 == 0 )
bc -> moveto ( bc, p->x, p->y, i % 3 ) ;
else
bc -> lineto ( bc, p->x, p->y ) ;
bc -> curveto ( bc, 233, 150, 267, 150, 300, 100 ) ;
bc -> track_seg ( bc, i ) ;
}
return src_len % 2 == 0 ;
}
-- spiro.py
from ctypes import *
# incomplete struct definition needed for pointer below
class bezctx ( Structure ) : pass
# pointer to function types for callback
MoveToFnType = CFUNCTYPE ( None, POINTER ( bezctx ), c_double, c_double, c_bool )
LineToFnType = CFUNCTYPE ( None, POINTER ( bezctx ), c_double, c_double )
CurveToFnType = CFUNCTYPE ( None, POINTER ( bezctx ), c_double, c_double, c_double, c_double, c_double, c_double )
TrackSegmentFnType = CFUNCTYPE ( None, POINTER ( bezctx ), c_uint )
# completing the struct definition
bezctx._fields_ = [ ( "moveto" , MoveToFnType ),
( "lineto" , LineToFnType ),
( "curveto" , CurveToFnType ),
( "track_seg", TrackSegmentFnType ) ]
# the python callbacks
def moveTo ( bc, x, y, startsOpenPath ) :
print ( "moveTo", bc, x, y, startsOpenPath )
def lineTo ( bc, x, y ) :
print ( "lineTo", bc, x, y )
def curveTo ( bc, c1x, c1y, c2x, c2y, x, y ) :
print ( "curveTo", bc, c1x, c1y, c2x, c2y, x, y )
def trackSegment ( bc, start_node_idx ) :
print ( "trackSegment", bc, start_node_idx )
# instance of struct
bc = bezctx ()
bc . moveto = MoveToFnType ( moveTo )
bc . lineto = LineToFnType ( lineTo )
bc . curveto = CurveToFnType ( curveTo )
bc . track_seg = TrackSegmentFnType ( trackSegment )
# another struct
class spiro_cp ( Structure ) :
_fields_ = [ ( "x", c_double ), ( "y", c_double ), ( "ty", c_char ) ]
# array of struct instances
srclist = [ spiro_cp ( 147, 215, b'o' ),
spiro_cp ( 168, 136, b'o' ),
spiro_cp ( 294, 184, b'[' ),
spiro_cp ( 381, 136, b']' ),
spiro_cp ( 445, 204, b'c' ),
spiro_cp ( 364, 235, b'c' ),
spiro_cp ( 266, 285, b'v' ) ]
src = ( spiro_cp * len ( srclist ) ) ( *srclist )
# open the sharedlib
libspiro = CDLL ( "libspiro.so" )
spiro_to_bezier_strict = libspiro.spiro_to_bezier_strict
# call the C function
spiro_to_bezier_strict ( src, len ( src ), bc )
-- bash session
$ python3 spiro-ctypes.py
147 215 o
Segmentation fault (core dumped)
I have the below C program spiro.c (obviously a simplified testcase) which I compile to a sharedlib using clang -fPIC -shared -o libspiro.so spiro.c, sudo cp to /usr/lib and am trying to call from a Python script spiro.py using ctypes. However it would seem that the first call to the callback results in a segfault. (The line before the callback is executed.) I tried debugging using gdb but perhaps because of my insufficient knowledge I couldn't find out what is causing the problem.
I hope some of the kind knowledgeable souls here can help me out:
-- spiro.c
# include <stdbool.h>
# include <stdio.h>
typedef struct _bezctx bezctx ;
struct _bezctx {
void ( * moveto ) ( bezctx * bc, double x, double y, bool starts_open_path ) ;
void ( * lineto ) ( bezctx * bc, double x, double y ) ;
void ( * curveto ) ( bezctx * bc, double c1x, double c1y, double c2x, double c2y, double x, double y ) ;
void ( * track_seg ) ( bezctx * bc, unsigned int start_node_idx ) ;
} ;
typedef struct {
double x, y ;
char ty ;
} spiro_cp ;
bool spiro_to_bezier_strict ( const spiro_cp src [], int src_len, bezctx * bc ) {
for ( int i = 0 ; i < src_len ; ++i ) {
const spiro_cp * p = &(src) ;
printf ( "%g %g %c\n", p->x, p->y, p->ty ) ;
if ( i % 2 == 0 )
bc -> moveto ( bc, p->x, p->y, i % 3 ) ;
else
bc -> lineto ( bc, p->x, p->y ) ;
bc -> curveto ( bc, 233, 150, 267, 150, 300, 100 ) ;
bc -> track_seg ( bc, i ) ;
}
return src_len % 2 == 0 ;
}
-- spiro.py
from ctypes import *
# incomplete struct definition needed for pointer below
class bezctx ( Structure ) : pass
# pointer to function types for callback
MoveToFnType = CFUNCTYPE ( None, POINTER ( bezctx ), c_double, c_double, c_bool )
LineToFnType = CFUNCTYPE ( None, POINTER ( bezctx ), c_double, c_double )
CurveToFnType = CFUNCTYPE ( None, POINTER ( bezctx ), c_double, c_double, c_double, c_double, c_double, c_double )
TrackSegmentFnType = CFUNCTYPE ( None, POINTER ( bezctx ), c_uint )
# completing the struct definition
bezctx._fields_ = [ ( "moveto" , MoveToFnType ),
( "lineto" , LineToFnType ),
( "curveto" , CurveToFnType ),
( "track_seg", TrackSegmentFnType ) ]
# the python callbacks
def moveTo ( bc, x, y, startsOpenPath ) :
print ( "moveTo", bc, x, y, startsOpenPath )
def lineTo ( bc, x, y ) :
print ( "lineTo", bc, x, y )
def curveTo ( bc, c1x, c1y, c2x, c2y, x, y ) :
print ( "curveTo", bc, c1x, c1y, c2x, c2y, x, y )
def trackSegment ( bc, start_node_idx ) :
print ( "trackSegment", bc, start_node_idx )
# instance of struct
bc = bezctx ()
bc . moveto = MoveToFnType ( moveTo )
bc . lineto = LineToFnType ( lineTo )
bc . curveto = CurveToFnType ( curveTo )
bc . track_seg = TrackSegmentFnType ( trackSegment )
# another struct
class spiro_cp ( Structure ) :
_fields_ = [ ( "x", c_double ), ( "y", c_double ), ( "ty", c_char ) ]
# array of struct instances
srclist = [ spiro_cp ( 147, 215, b'o' ),
spiro_cp ( 168, 136, b'o' ),
spiro_cp ( 294, 184, b'[' ),
spiro_cp ( 381, 136, b']' ),
spiro_cp ( 445, 204, b'c' ),
spiro_cp ( 364, 235, b'c' ),
spiro_cp ( 266, 285, b'v' ) ]
src = ( spiro_cp * len ( srclist ) ) ( *srclist )
# open the sharedlib
libspiro = CDLL ( "libspiro.so" )
spiro_to_bezier_strict = libspiro.spiro_to_bezier_strict
# call the C function
spiro_to_bezier_strict ( src, len ( src ), bc )
-- bash session
$ python3 spiro-ctypes.py
147 215 o
Segmentation fault (core dumped)