在自定义typemap中重用SWIG映射

2024-04-20 13:41:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在为一个C++库编写Python包装,我想使用Sigg。在我的C++库中,我有一个具有以下签名的方法:

std::vector<SomeClass> getMembers();

现在我知道SWIG有内置的std::vector支持,但是我想显式地将std::vector转换为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接口,我会非常高兴!你知道吗


Tags: 方法类型sizetypetemplatevalswigpyobject
1条回答
网友
1楼 · 发布于 2024-04-20 13:41:55

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

我不同意您的评估,即在Python中,将std::vector映射到list更干净—您总是复制并访问该向量的每个成员来完成此操作。实际上,您复制了原始容器并用两个容器结束,因此对Python列表的更改不会反映在基础C++容器上。Python提供的std::vector包装应该实现您关心的协议,以在默认情况下启用pythonic语法,并且可以正确地支持ABCs。。(如果他们不这样做,我就要写补丁了!)你知道吗

相关问题 更多 >