我目前正在为要使用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界面实现我想要的功能,我将非常高兴!
答案 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。(如果我不愿意写补丁, !)