Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python helper函数中的swig宏$descriptor_Python_C++_Swig - Fatal编程技术网

Python helper函数中的swig宏$descriptor

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

简介

我的典型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
};
%{//按原样复制此块
#包括
静态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
即可获得第二个参数的正确值