简介
我的典型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, 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
};
但我想避免在SWIGTYPE_p_CppClass
中明确使用get_CppClass_from_swig_object
。
按原样,我不能像我想的那样使用$descriptor(CppClass)
swig宏,因为%{ ... %}
块被复制为-is而不是swig解释,因此{{ 1}} swig宏不会被解释。另一方面,如果我删除$descriptor
并使用%
块,swig将尝试包装整个{ ... }
和get_CppClass_from_swig_object
类,而不是简单地定义它们它们可以在typemap中使用。
问题
如何更改文件结构并允许在转换助手中使用convert_to_CppClass
宏?
TL; DR
$descriptor
块既未经过预处理也未被swig包裹%{...%}
块都经过预处理和包装(但可以防止使用前面的{...}
进行swig预处理的小块)答案 0 :(得分:1)
我不认为有一种方法可以对%{...%}
的内容进行预处理,但不对其进行预处理 - 对于预处理器所做的大多数事情,它依赖于实际实例化的类型映射填充替换信息(虽然$descriptor
仍然可以工作,但我过去一直希望这样做。)
我通常的解决方案是将SWIG类型信息作为参数传递给类似的函数,例如:
%{ //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
这意味着当您在类型地图中使用get_CppClass_from_swig_object
时,您需要做的只是使用$1_descriptor
或$descriptor
来获取第二个参数的正确值。