python - 辅助函数中的 swig 宏 $descriptor

标签 python c++ swig

简介

我典型的swig接口(interface)文件类似如下:

%{ //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
};

但我想避免在 get_CppClass_from_swig_object 中显式使用 SWIGTYPE_p_CppClass

照原样,不可能像我想的那样使用 $descriptor(CppClass) swig 宏,因为 %{ ... %} block 按原样复制,而不是由 swig 解释,因此 $descriptor swig 宏不会被解释。另一方面,如果我删除 % 并使用 { ... } block ,swig 会尝试包装整个 get_CppClass_from_swig_objectconvert_to_CppClass 类,而不是简单地定义它们,以便它们可以在类型映射中使用。

问题

如何更改我的文件结构并允许在转换助手中使用 $descriptor 宏?

长话短说

  • %{...%} block 既没有被预处理也没有被 swig 包装
  • {...} block 都经过预处理和包装(但可以通过前面的 % 防止小块进行 swig 预处理)
  • 我怎样才能使 swig 预处理而不是包装一段代码?

最佳答案

我认为没有办法对 %{...%} 的内容进行预处理,但不进行包装 - 对于预处理器所做的大部分工作,它依赖于类型映射来实际上被实例化以填充替换信息(尽管 $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 来获取正确的第二个参数的值。

关于python - 辅助函数中的 swig 宏 $descriptor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47198551/

相关文章:

python - 如何正确排序/排列类(class)成员

c++ - 如何将 SWIG 与 "using"一起使用

python - Python REPL 中默认的 pretty-print

python - 使用 BeautifulSoup 解码 html 实体

c++ - 在 Linux 上的发布/优化二进制文件中的信号处理程序中打印回溯

C++ Qt 写入 unix 套接字

c++ - swig perl typemap(out) std::vector<std::string> 没有在 perl 中返回所需的输出

c - 函数类型 "extern __declspec(dllimport) INT __cdecl"在 C/C++ 或 SWIG 中有意义吗?

python - 如何从 pandas 数据框中选择平均值大于某个限制的列?

python - 在 IPython Notebook (Bokeh) 中绘制大型数据集