Python helper函数中的swig宏$descriptor
简介 我的典型swig接口文件类似于以下内容:Python helper函数中的swig宏$descriptor,python,c++,swig,Python,C++,Swig,简介 我的典型swig接口文件类似于以下内容: %{ //COPY THIS BLOCK AS IS #include <headers.h> static CppClass* get_CppClass_from_swig_object(PyObject* obj) { void* self_obj = nullptr; int ok = SWIG_Python_ConvertPtr(obj, &self_obj, S
%{ //COPY THIS BLOCK AS IS
#include <headers.h>
static CppClass* get_CppClass_from_swig_object(PyObject* obj)
{
void* self_obj = nullptr;
int ok = SWIG_Python_ConvertPtr(obj, &self_obj, SWIGTYPE_p_CppClass, 0);
if(!SWIG_IsOK(ok))
{
PyErr_SetString(PyExc_TypeError, "Object must be a CppClass");
return nullptr;
}
return reinterpret_cast<CppClass*>(self_obj);
}
static CppClass convert_to_CppClass(PyObject* py_obj)
{
CppClass* converted_ptr = get_CppClass_from_swig_object(py_obj);
if(converted_ptr==nullptr)
throw std::runtime_error("Python object is not a CppClass");
return CppClass(*converted_ptr);
}
%}
%typemap(in) std::vector<CppClass>& (std::vector<CppClass> temp) {
try{
temp = SequenceConverter::to_vector<CppClass>($input, convert_to_CppClass);
$1 = &temp;
}catch(std::exception& e){
PyErr_SetString(PyExc_RuntimeError, e.what());
SWIG_fail;
}
}
%typemap(typecheck, precedence=SWIG_TYPECHECK_CPPCLASS_VECTOR) std::vector<CppClass>& {
$1 = 0;
if(PyTuple_Check($input))
$1 = 1;
else if(PyList_Check($input))
$1 = 1;
}
class CppClass
{
public:
CppClass();
CppClass(const CppClass& other);
//other methods
};
%{//按原样复制此块
#包括
静态CPPGlass*从\u swig\u对象(PyObject*obj)获取\u CPPGlass\u
{
void*self_obj=nullptr;
int ok=SWIG_Python_ConvertPtr(obj和self_obj,SWIGTYPE_p_cppglass,0);
如果(!SWIG_IsOK(ok))
{
PyErr_SetString(PyExc_TypeError,“对象必须是CppClass”);
返回空ptr;
}
返回重新解释投射(自我对象);
}
静态CppClass转换为CppClass(PyObject*py\u obj)
{
CppClass*转换的\u ptr=从\u swig\u对象(py\u obj)获取\u CppClass\u;
if(已转换的_ptr==nullptr)
抛出std::runtime_错误(“Python对象不是CppClass”);
返回CPP类(*转换的ptr);
}
%}
%类型映射(in)标准::向量和(标准::向量温度){
试一试{
temp=SequenceConverter::to_vector($input,convert_to_CppClass);
$1=&temp;
}捕获(标准::异常&e){
PyErr_SetString(PyExc_RuntimeError,例如what());
SWIG_失败;
}
}
%typemap(typecheck,优先级=SWIG\u typecheck\u cppu class\u VECTOR)std::VECTOR&{
$1 = 0;
if(PyTuple_Check($input))
$1 = 1;
else if(PyList_检查($input))
$1 = 1;
}
类CPP类
{
公众:
CppClass();
CppClass(常数CppClass和其他);
//其他方法
};
但我希望避免在get\u CppClass\u from\u swig\u object
中显式使用SWIGTYPE\u p\u CppClass
照目前的情况,不可能像我所希望的那样使用$descriptor(CppClass)
swig宏,因为%{…%}
块是按-原样复制的,而不是由swig解释的,因此$descriptor
swig宏不会被解释。另一方面,如果我删除%
并使用{…}
块,swig将尝试包装整个get\u CppClass\u from\u swig\u object
和convert\u to \u CppClass
类,而不是简单地定义它们以便在类型映射中使用
问题
如何更改文件结构并允许在转换帮助程序中使用$descriptor
宏
TL;DR
块既不被swig预处理也不被swig包装%{…%}
块都是预处理和包装的(但是可以防止小片段使用前面的{…}
进行swig预处理)%
- 如何使swig进行预处理而不包装一段代码
%{…%}
的内容进行预处理,但不进行包装-对于预处理器所做的大部分工作,它依赖于一个类型映射来实际实例化以填充替换信息(尽管$descriptor
仍然可以工作,而且我在过去也希望如此)
我通常的解决方案是将SWIG type info作为参数传递给这样的函数,例如:
%{ //COPY THIS BLOCK AS IS
#include <headers.h>
static CppClass* get_CppClass_from_swig_object(PyObject* obj, swig_type_info *ty)
{
//... use ty instead of $descriptor here
%{//按原样复制此块
#包括
静态CppClass*从\u swig\u对象获取\u CppClass\u(PyObject*obj,swig\u type\u info*ty)
{
//…在这里使用ty而不是$descriptor
这意味着在类型映射中使用get\u cppglass\u from\u swig\u object
时,只需使用$1\u descriptor
或$descriptor
即可获得第二个参数的正确值