代码之家  ›  专栏  ›  技术社区  ›  totoro

在Python SWIG中包装void*参数

  •  2
  • totoro  · 技术社区  · 8 年前

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

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

    在库中 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 *'
    
    2 回复  |  直到 8 年前
        1
  •  2
  •   Flexo - Save the data dump sunny moon    8 年前

    如果你只是想通过 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输入。如何处理它取决于您,如果保留该对象,则需要增加引用计数。

        2
  •  1
  •   totoro    8 年前

    事实证明这很简单。我想要 value PyObject * 这样我就可以自己输入check并进行转换。下面是我想要包装的函数:

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