gpt4 book ai didi

python - 用于 SWIG、Python 的 C 函数错误代码的 %typemap 和 %exception

转载 作者:太空宇宙 更新时间:2023-11-04 01:38:52 26 4
gpt4 key购买 nike

我有一些 C 代码要公开给 Python。它有这样的调用约定:

int add(int a, int b, int *err)

返回值是 (a+b) 或其他什么,但如果出现问题,那么我会在 *err 中得到一个错误代码。我想包装这个函数,从 Python 的角度来看,它的行为如下:

def add(a,b):
if something_bad:
raise RuntimeError("something bad")
return a+b

这应该很容易吧?但我不这么认为。

这是我的一些有用的东西,但要注意 myerr3 的杂乱无章:

%module myswig
%feature("autodoc","1");

%{
int add(int a, int b, int *err){
if(a < 0)*err = 1;
if(b < 0)*err = 2;
return a+b;
}

char *err_string(int err){
switch(err){
case 1:return "first argument was less than 0";
case 2:return "second argument was less than 0";
default:return "unknown error";
}
}
%}

%typemap(in,numinputs=0) int *err (int myerr = 0){
$1 = &myerr;
};

%exception{
$action
if(myerr3 != 0){
PyErr_SetString(PyExc_RuntimeError,err_string(myerr3));
return NULL;
}
};

int add(int a, int b, int *err);

这就像它应该的那样,例如

import myswig
print "add(1,1) = "
print myswig.add(1,1)
# prints '2'

print "add(1,-1) = "
print myswig.add(1,-1)
# raises an exception

# we never get here...
print "here we are"

但我不能真正使用这个解决方案,因为如果我有另一个功能,比如

int add(int a, int b, int c, int *err)

然后我的 myerr3 kludge 就会崩溃。

在不改变 C 代码调用约定的情况下,有什么更好的方法可以解决这个问题?

最佳答案

诀窍不是使用%exception,而是定义%typemap(argout)。也不要直接引用您的临时变量。 %typemap(in) 抑制了目标语言中的参数并提供了一个本地临时变量,但您仍应在 %typemap(argout) 中引用参数本身。这是原始 .i 文件的修改版本。我还添加了更多通用异常抛出,因此它也适用于其他语言:

%module x
%feature("autodoc","1");

// Disable some Windows warnings on the generated code
%begin %{
#pragma warning(disable:4100 4127 4211 4706)
%}

%{
int add(int a, int b, int *err){
if(a < 0)*err = 1;
if(b < 0)*err = 2;
return a+b;
}

char *err_string(int err){
switch(err){
case 1:return "first argument was less than 0";
case 2:return "second argument was less than 0";
default:return "unknown error";
}
}
%}

%include <exception.i>

%typemap(in,numinputs=0) int *err (int myerr = 0) {
$1 = &myerr;
}

%typemap(argout) int* err {
if(*$1 != 0) {
SWIG_exception(SWIG_ValueError,err_string(*$1));
}
}

int add(int a, int b, int *err);

结果如下:

Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import x
>>> x.add(1,1)
2
>>> x.add(3,4)
7
>>> x.add(-1,4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "x.py", line 73, in add
return _x.add(*args)
RuntimeError: first argument was less than 0
>>> x.add(3,-1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "x.py", line 73, in add
return _x.add(*args)
RuntimeError: second argument was less than 0

关于python - 用于 SWIG、Python 的 C 函数错误代码的 %typemap 和 %exception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9456723/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com