我使用C
调用Python/numpy
中ctypes
编写的共享库。但是,当exit
C
中使用iPython
函数时,C
会发生一些意外结果。
考虑以下示例,其中数组“A”的第一项在C
中进行了修改。如果值为负,则应引发异常。
#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);
}
// change "A[0]" to it's square
A[0] = pow(A[0],2);
}
- 代码:
gcc -c -fPIC fun.c
gcc -shared -o test.so fun.o
使用
编译Python
包裹import numpy as np
import ctypes
# include shared library
lib = ctypes.CDLL("./test.so")
# link to C-program, including input-typing
cfun = lib.cfun
cfun.restype = None
cfun.argtypes = [ np.ctypeslib.ndpointer(ctypes.c_double,flags="C_CONTIGUOUS") ]
# simple example
A = np.arange((5),dtype='float')+2.
cfun(A)
print A
# expected output: [ 4. 3. 4. 5. 6.]
# simple example
A[0] = -10.0
cfun(A)
print A
# expected output: exception, no output from "print A"
- 代码:
[ 4. 3. 4. 5. 6.]
Negative value of A[0] encountered
当我从命令行运行此代码时,程序会执行应有的操作。输出:
iPython
然而,当我从iPython
C
也存在。我认为最优雅的解决方案是引入错误流作为(返回)参数来表示成功或失败。但是我真的想避免这种情况。我使用了广泛的{{1}}代码。引入错误流会使所有函数之间的依赖性过度复杂化。
请帮忙!
答案 0 :(得分:2)
exit
调用系统的退出函数并终止正在运行的进程,在你的情况下是ipython。在C中完成错误处理的方法是设置一些全局错误变量并返回状态标志
#include <math.h>
char *error_string;
extern char* get_error_string() {
return 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";
return -1;
}
// change "A[0]" to it's square
A[0] = pow(A[0],2);
return 0;
}
并在Python中测试错误:
import numpy as np
import ctypes
# include shared library
lib = ctypes.CDLL("./test.so")
# link to 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())
return method
# link to 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 example
A = np.arange((5),dtype='float')+2.
cfun(A)
print A
# expected output: [ 4. 3. 4. 5. 6.]
# simple example
A[0] = -10.0
cfun(A)
print A
# expected output: exception, no output from "print A"