辅助函数中的swig宏$描述符

时间:2017-11-09 09:45:36

标签: 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, 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预处理的小块)
  • 如何进行swig预处理但不包装一段代码?

1 个答案:

答案 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来获取第二个参数的正确值。