根据C退出代码在ctypes中捕获异常 [英] Catch exception in ctypes based on C-exit code

查看:204
本文介绍了根据C退出代码在ctypes中捕获异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在调用使用 Python / numpy C 编写的共享库ctypes 。但是,当在 C 中使用 exit 函数时,这会产生奇妙的效果,而 iPython

I am calling a shared-library written in C from Python/numpy using ctypes. This works fantastic, however, when the exit function is used in C some unexpected results occur in iPython.

考虑以下示例,其中数组 A的第一项在 C中进行了修改。如果该值为负,则应引发异常。

Consider the following example, where the first item of an array "A" is modified in C. If the value is negative an exception should be raised.

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);
  }

  // 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 -code:

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"

当我从命令行运行此代码时,程序将执行应有的操作。输出:

When I run this code from the command-line the program does what it should. The output:

[ 4.  3.  4.  5.  6.]
Negative value of A[0] encountered

但是当我从 iPython


  • 想要的行为是引发了某种异常,

  • 当前行为是,当遇到错误时, iPython 也存在。

  • the wanted behavior is that some kind of exception is raised,
  • the current behavior is that when the error is encountered also iPython exists.

我相信最优雅的解决方案是引入错误流作为(返回)参数,以指示成功或失败。但是我真的很想避免这种情况。我使用了广泛的 C 代码。引入错误流会使所有函数之间的依赖性过于复杂。

I believe the most elegant solution is to introduce an error-stream as (return) argument signaling the success or failure. However I really would like to avoid this. I use an extensive C-code. Introducing an error-stream would overly complicate the dependency between all the functions.

请帮助!

推荐答案

exit 调用系统的退出功能并终止正在运行的进程(在您的情况下为ipython)。在C中执行错误处理的方式是设置一些全局错误变量并返回状态标志

exit calles the system's exit function and terminates the process running, in your case ipython. The way error handling is done in C is by setting some global error variable and returning a status flag

#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中测试错误:

and in Python test for errors:

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"

这篇关于根据C退出代码在ctypes中捕获异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆