我使用Python SWIG包装此lib,其函数如下所示:
int set_option(Foo *foo, const char *name, void *value);
在lib const char *name
中映射到我有权查询的类型:int
,char *
,char **
。
默认情况下生成的包装器代码只接受包装的void *
(自然地)。
使包装方法接受任何 Python对象作为参数,并在我自己的C代码中进行类型检查和Python到C转换的最佳方法是什么?
我的猜测是某种类型的地图,但唉,我无法弄明白。
@Goodies
In [12]: lib.set_option(foo, "option", "value")
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-12-4ccf706b5c50> in <module>()
----> 1 lib.set_option(foo, "option", "value")
TypeError: in method 'set_option', argument 3 of type 'void *'
答案 0 :(得分:2)
如果您只是想使用PyObject
将%extend
传递给某些内容,您可以修改您所拥有的内容,只需编写以下内容:
%extend Foo {
int set_option(const char *name, PyObject *value) {
// Here value is now a PyObject *, so work with that.
// $self is Foo *foo
return 0;
}
};
不需要类型图,此函数现在接受任何Python输入。你用它做什么取决于你,如果你保留对象,你需要增加引用计数。
答案 1 :(得分:1)
原来这很简单。我希望value
为PyObject *
,因此我可以输入检查并自行转换。这是我想要包装的功能:
int set_option(Foo *foo, const char *name, void *value);
此解决方案还使其成为class Foo
的方法。
%extend Foo {
int set_option(const char *name, void *value) {
// Here value is now a PyObject *, so work with that.
// $self is Foo *foo
return 0;
}
};
%typemap(in) (void *value) {
$1 = (void *) $input;
};