From: Martin Landa on 5 Aug 2010 13:50 Hi, is it possible to pass pointer to a method using ctypes. Sample code: ... G_set_error_routine(byref(self._print_error)) ... def _print_error(self, msg, type): """!Redirect stderr""" self.log.write(msg) gives me G_set_error_routine(byref(self._print_error)) TypeError: byref() argument must be a ctypes instance, not 'instancemethod' C function G_set_error_routine is defined as void G_set_error_routine(int (*error_routine) (const char *, int)) Thanks in advance for any pointers. Martin
From: Nobody on 5 Aug 2010 15:32 On Thu, 05 Aug 2010 10:50:21 -0700, Martin Landa wrote: > is it possible to pass pointer to a method using ctypes. I don't know about methods, but it works for functions. > Sample code: > > ... > G_set_error_routine(byref(self._print_error)) This won't work; you have to be more explicit, e.g.: errtype = CFUNCTYPE(c_int, POINTER(c_char), POINTER(c_int)) errfunc = errtype(print_error) G_set_error_routine(errfunc) NOTE: be sure to keep a reference to the wrapper, as ctypes doesn't hold references itself. IOW, you can't replace the above with: errtype = CFUNCTYPE(c_int, POINTER(c_char), POINTER(c_int)) G_set_error_routine(errtype(print_error)) If you do this, the wrapper is eligible for garbage collection as soon as G_set_error_routine() returns, and will probably have vanished by the time that G_fatal_error() gets called. For more information see: http://docs.python.org/library/ctypes.html#callback-functions
From: Martin Landa on 6 Aug 2010 16:10 Hi, On Aug 5, 9:32 pm, Nobody <nob...(a)nowhere.com> wrote: > I don't know about methods, but it works for functions. > > > Sample code: > > > ... > > G_set_error_routine(byref(self._print_error)) > > This won't work; you have to be more explicit, e.g.: > > errtype = CFUNCTYPE(c_int, POINTER(c_char), POINTER(c_int)) > errfunc = errtype(print_error) > G_set_error_routine(errfunc) the C function is defined as G_set_error_routine = _libs['grass_gis. 7.0.svn'].G_set_error_routine G_set_error_routine.restype = None G_set_error_routine.argtypes = [CFUNCTYPE(UNCHECKED(c_int), String, c_int)] I defined in Python function print_error() def print_error(self, msg, type): print msg, type and errtype = CFUNCTYPE(UNCHECKED(c_int), String, c_int) errfunc = errtype(print_error) G_set_error_routine(errfunc) unfortunately the application crashes when print_error() is called from C library static void vfprint_error(int type, const char *template, va_list ap) { char buffer[2000]; /* G_asprintf does not work */ vsprintf(buffer, template, ap); G_debug(5, "print_error(): msg = \"%s\" type = %d", buffer, type); print_error(buffer, type); } Any idea how to solve it. Thanks, Martin
From: Martin Landa on 6 Aug 2010 16:18 Hi, On Aug 6, 10:10 pm, Martin Landa <landa.mar...(a)gmail.com> wrote: > Any idea how to solve it. Thanks, Martin I overlooked note """ Make sure you keep references to CFUNCTYPE objects as long as they are used from C code. ctypes doesnt, and if you dont, they may be garbage collected, crashing your program when a callback is made. """ If I defined errtype and errfunc as global variable everything works. Thanks again for your help. Martin
From: Martin Landa on 7 Aug 2010 06:46 Hi, On Aug 5, 9:32 pm, Nobody <nob...(a)nowhere.com> wrote: > errtype = CFUNCTYPE(c_int, POINTER(c_char), POINTER(c_int)) > errfunc = errtype(print_error) > G_set_error_routine(errfunc) the problem occurs when restype is not None, but c_int. E.g. if hasattr(_libs['grass_gis'], 'G_set_error_routine'): G_set_error_routine = _libs['grass_gis'].G_set_error_routine G_set_error_routine.restype = c_int G_set_error_routine.argtypes = [CFUNCTYPE(UNCHECKED(c_int), String, c_int)] errtype = CFUNCTYPE(UNCHECKED(c_int), String, c_int) errfunc = errtype(print_error) or errtype = CFUNCTYPE(c_int, String, c_int) errfunc = errtype(print_error) ends up with error G_set_error_routine(errfunc) TypeError: in method 'G_set_error_routine', argument 1 of type 'int (*) (char const *,int)' The first argument of CFUNCTYPE defines result type (restype), AFAIU that should work. Thanks in advance again, Martin
|
Next
|
Last
Pages: 1 2 Prev: easy question on parsing python: "is not None" Next: pre-uninstall script in bdist_wininst |