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

Reusing SWIG mappings in custom typemap

本文关键字:SWIG 映射 自定义 类型 型图      更新时间:2023-10-16

我目前正在为一个C++库开发一个Python包装器,我想使用它SWIG。在我的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界面实现我想要的东西,我会非常高兴!

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

我不同意您的评估,即在 Python 中将std::vector映射到列表更干净 - 您最终总是复制并访问该向量的每个成员来执行此操作。实际上,您创建了原始容器的副本,最终得到了两个容器,因此对 Python 列表的更改不会反映在基础C++容器上。Python提供的std::vector包装应该实现你关心的协议,以默认启用pythonic语法,并且可以正确支持ABC。(如果他们不这样做,我愿意写补丁!