在自定义类型图中重用SWIG映射

时间:2018-08-18 09:35:45

标签: python c++ swig

我目前正在为要使用SWIG的C ++库开发Python包装器。在我的C ++库中,我有一个带有以下签名的方法:

std::vector<SomeClass> getMembers();

现在,我知道SWIG具有内置的std :: vector支持,但是我想将std :: vectors显式转换为Python列表(我只是认为它更干净)。为此,我具有以下类型映射:

template<typename T>
PyObject* toList(vector<T> vec){
    size_t size = vec.size();
    PyObject *o = PyList_New(size);
    for(size_t i = 0; i < size; i++){
        PyList_SetItem(o, i, toPythonInstance<T>(vec[i]));
    }
    return o;
}

%define OUTPUT_VEC_TO_LIST(type)
%typemap (out) std::vector<type> {
    $result = toList<type>($1);
}
%enddef

现在使用模板方法:

template<T>
PyObject* toPythonInstance(T& val){}

可以专门添加对必要数据类型的支持。我现在面临的问题如下:

SomeClass 由SWIG自动包装。所以我想做的就是在我的向量类型映射中重用这个包装器,即具有以下内容:

template<>
PyObject* toPythonInstance<SomeClass>(SomeClass& val){
    //call some SWIG macro to automatically wrap the given instance to
    //a Python object
}

检查SWIG生成的代码,我已经找到以下功能

SWIG_NewPointerObj(...);
SWIG_ConvertPtr(...);

这似乎完全可以满足我的要求。但是,我不想干扰SWIG的任何内部。因此,如果有人知道如何使用“公共” SWIG界面实现我想要的功能,我将非常高兴!

1 个答案:

答案 0 :(得分:1)

SWIG实际上使大量的运行时信息成为外部接口的一部分,有关详细信息,请参见http://www.swig.org/Doc3.0/Modules.html#Modules_external_run_time。这包括您可能需要努力的功能。

我不同意您的评估,认为在Python中将std::vector映射到列表更干净-您总是最终要复制并访问该向量的每个成员才能做到这一点。实际上,您将复制原始容器并以两个容器结束,因此对Python列表的更改不会反映在基础C ++容器上。 Python提供的std::vector包装应该实现您关心的协议,以默认情况下启用pythonic语法,并且也可以正确支持ABCs。(如果我不愿意写补丁, !)