在 Python SWIG 中包装一个 void * 参数

Wrapping a void * argument in Python SWIG

我正在用 Python SWIG 包装这个库,它的函数如下所示:

int set_option(Foo *foo, const char *name, void *value);

在库中 const char *name 映射到我有权查找的类型:intchar *char **.

默认生成的包装代码只接受包装的void *(自然)。

使包装方法接受 any Python 对象作为参数并进行类型检查和 Python 到 C 的最佳方法是什么在我自己的 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 *'

事实证明这很简单。我想要 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) {
         = (void *) $input;
};

如果您只想将 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 输入。你用它做什么取决于你,如果你保留这个对象,你需要增加引用计数。