SWIP包裹向量(C++ + Python)如何识别内部向量作为代理对象?

2024-10-01 13:42:38 发布

您现在位置:Python中文网/ 问答频道 /正文

<>我面对的是一个类似的问题,{^ a1}——但它不仅仅是简单的C++解析。我的C++代码

中有以下内容
namespace ns {
    typedef unsigned long long uint64_t;
    typedef std::vector<uint64_t> Vector;
    typedef std::vector<Vector> VectorOfVectors;

    class MyClass {
        /// ...

        /// Returns a reference to the internal vector allocated in C++ land
        const VectorOfVectors &GetVectors() const;
    };
}

在饮料包装袋里

^{pr2}$

所以包装工作得很好,包括类,我可以检索类的向量向量,好的:

import myswig
m = myswig.MyClass()
v = m.GetVectors()
print v

这给了我:

<myswig.VUint64V; proxy of <Swig Object of type 'std::vector< std::vector< ns::uint64_t,std::allocator< ns::uint64_t > > > *' at 0x994a050> >

但是如果我访问向量中的一个元素,我不会得到一个myswig.Uint64V-这是我的问题。在

x = v[0]
print x

我希望得到的是:

<myswig.Uint64V; proxy of <Swig Object of type 'std::vector< ns::uint64_t, std::allocator< ns::uint64_t > > *' at 0x994a080> >

相反,我得到了:

(<Swig Object of type 'ns::uint64_t *' at 0x994a080>, <Swig Object of type 'ns::uint64_t *' at 0x994a098>) 

也就是说,向量向量的索引给了我一个2项元组,而不是我需要的向量类的代理(因此访问内部向量和访问其他向量一样容易)。在

我也得到了警告:

swig/python detected a memory leak of type 'ns::uint64_t *', no destructor found.

因为当然没有为这个类型定义析构函数。在

有什么想法吗?在


Tags: ofobjecttype向量atlongswigstd
1条回答
网友
1楼 · 发布于 2024-10-01 13:42:38

我和我的一个同事一起研究这个问题,我们设法想出了一些解决办法。在

首先,在SWIG.i文件中,定义这个预处理器变量很重要:

%{
#   define SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS 
%}

然后,为了确保front()、back()、operator[]等方法返回的引用实际映射到内部向量的正确代理类型,以下类型映射有助于:

^{pr2}$

我们还发现,如果您希望将ns::uint64泳t视为python long变量(相当于C unsigned long long),则需要一些进一步的类型映射,以确保使用值和引用的向量方法只使用64位整数值。在

// In __getitem__()
%typemap(out) ns::uint64_t {
    $result = PyLong_FromUnsignedLongLong($1);
}
// Not used (but probably useful to have, just in case)
%typemap(in) ns::uint64_t {
    $1 = PyLong_AsUnsignedLongLong($input);
}
// In pop()
%typemap(out) std::vector<ns::uint64_t>::value_type {
    $result = PyLong_FromUnsignedLongLong($1);
}
// In __getitem__(), front(), back()
%typemap(out) std::vector<ns::uint64_t>::value_type & {
    $result = PyLong_FromUnsignedLongLong(*$1);
}
// In __setitem__(), append(), new Uint64Vector, push_back(), assign(), resize(), insert()
// This allows a python long literal number to be used as a parameter to the above methods. 
// Note the use of a local variable declared at the SWIG wrapper function scope,
// by placing the variable declaration in parentheses () prior to the open brace {
%typemap(in) std::vector<ns::uint64_t>::value_type & (std::vector<ns::uint64_t>::value_type temp) {
    temp = PyLong_AsUnsignedLongLong($input);
    $1 = &temp;
}

我希望这个解决方案对将来的人们有所帮助!在

相关问题 更多 >