Sunday, 15 January 2012

python - Catch exception in ctypes based on C-exit code -



python - Catch exception in ctypes based on C-exit code -

i calling shared-library written in c python/numpy using ctypes. works fantastic, however, when exit function used in c unexpected results occur in ipython.

consider next example, first item of array "a" modified in c. if value negative exception should raised.

the c-code:

#include <stdlib.h> #include <stdio.h> #include <math.h> extern void cfun(double* a) { // raise exception if a[0]<0.0 if ( a[0]<0.0 ) { printf("negative value of a[0] encountered\n"); exit(1); } // alter "a[0]" it's square a[0] = pow(a[0],2); }

which compiled using

gcc -c -fpic fun.c gcc -shared -o test.so fun.o

the wrapping python-code:

import numpy np import ctypes # include shared library lib = ctypes.cdll("./test.so") # link c-program, including input-typing cfun = lib.cfun cfun.restype = none cfun.argtypes = [ np.ctypeslib.ndpointer(ctypes.c_double,flags="c_contiguous") ] # simple illustration = np.arange((5),dtype='float')+2. cfun(a) print # expected output: [ 4. 3. 4. 5. 6.] # simple illustration a[0] = -10.0 cfun(a) print # expected output: exception, no output "print a"

when run code command-line programme should. output:

[ 4. 3. 4. 5. 6.] negative value of a[0] encountered

however when run python function ipython

the wanted behavior kind of exception raised, the current behavior when error encountered ipython exists.

i believe elegant solution introduce error-stream (return) argument signaling success or failure. avoid this. utilize extensive c-code. introducing error-stream overly complicate dependency between functions.

please help!

exit calles system's exit function , terminates process running, in case ipython. way error handling done in c setting global error variable , returning status flag

#include <math.h> char *error_string; extern char* get_error_string() { homecoming error_string; } extern int cfun(double* a) { // raise exception if a[0]<0.0 if ( a[0]<0.0 ) { error_string = "negative value of a[0] encountered\n"; homecoming -1; } // alter "a[0]" it's square a[0] = pow(a[0],2); homecoming 0; }

and in python test errors:

import numpy np import ctypes # include shared library lib = ctypes.cdll("./test.so") # link c-program, including input-typing get_error = lib.get_error get_error.restype = ctypes.c_char_p get_error.argtypes = [] def c_error_wrapper(func): def method(*args): status = func(*args) if status<0: raise runtimeerror(get_error()) homecoming method # link c-program, including input-typing cfun = lib.cfun cfun.restype = ctypes.c_int cfun.argtypes = [ np.ctypeslib.ndpointer(ctypes.c_double,flags="c_contiguous") ] cfun = c_error_wrapper(cfun) # simple illustration = np.arange((5),dtype='float')+2. cfun(a) print # expected output: [ 4. 3. 4. 5. 6.] # simple illustration a[0] = -10.0 cfun(a) print # expected output: exception, no output "print a"

python c ctypes

No comments:

Post a Comment