当前位置: 首页 > 面试题库 >

SWIG包装的向量载体(从C ++到python)-如何将内部向量识别为代理对象?

朱毅
2023-03-14
问题内容

我面临与包装std :: vector of std :: vectors,C ++ SWIG
Python
类似的问题-但这不仅是简单的C html" target="_blank">解析。我的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;
    };
}

并在SWIG包装器中

%module myswig    
// ...
%template(Uint64V) std::vector<ns::uint64_t>;
%template(VUint64V) std::vector<std::vector<ns::uint64_t> >;

因此,包括类在内的包装工作都很好,我可以检索向量的类的向量OK:

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.

因为当然没有为此类型定义的析构函数。

有任何想法吗?


问题答案:

我曾与我的一位同事合作过,我们设法提出了一些解决方案。

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

%{
#   define SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS 
%}

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

// In pop()
%typemap(out) std::vector<std::vector<ns::uint64_t> >::value_type { 
$result = SWIG_NewPointerObj(SWIG_as_voidptr(&$1), $descriptor(std::vector<ns::uint64_t>), 0 |  0 ); 
}

// In front(), back(), __getitem__()
%typemap(out) std::vector<std::vector<ns::uint64_t> >::value_type & { 
    $result = SWIG_NewPointerObj(SWIG_as_voidptr($1), $descriptor(std::vector<ns::uint64_t>), 0 |  0 ); 
}

我们还发现,如果您想将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;
}

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



 类似资料:
  • 我有一个C(而不是C)库,它一致地使用函数的第一个参数作为上下文对象(让我们调用类型),我想使用SWIG生成C#wrappers来保持这种调用风格(也就是说,不要把函数或多或少地孤立起来,而是把它们包装成某个类中的方法,并通过方法中的对象的引用访问)。 示例(C签名): 所需的C#API: 如果有人向我指出一个使用这种API风格的现有C(再次:不是C)库的SWIG生成的包装器,我也会很高兴;我什么

  • 使用C 14,我试图扩展此实现,以支持将在外部调用的ObserverCallback方法。 MyClass容器使用元组向量,其类型由可变模板指定。然后可以使用Access访问vector 我需要的是实现一个观察器,它应该向向量添加元素。由于元素的类型可以是元组中的任何类型,因此我也对其进行了模板化: 包装器类中似乎有错误: 作为参考,我还附上完整的源代码清单:

  • 我有一个整数向量: 考虑到将始终为偶数。 我只是想把相邻的元素转换成一对,像这样: i、 两个相邻的元件连接成一对。 我可以使用什么STL算法轻松实现这一点?有没有可能通过一些标准算法来实现这一点? 当然,我可以很容易地编写一个旧的索引for循环来实现这一点。但我想知道,使用基于范围的for循环或任何其他STL算法(如等)最简单的解决方案是什么样的。

  • 我试图将元组向量转换为向量[人],但上面的代码会导致强制转换异常,即使存在隐式的元组-人转换函数? 线程“main”java中出现异常。lang.ClassCastException:scala。Tuple2无法转换为示例。例如,测试$人。测试$$anonfun$2$$anonfun$应用$1。在scala应用(测试scala:19)。收集迭代器$类。scala上的foreach(迭代器。scal

  • 本文向大家介绍C++ 向量迭代器,包括了C++ 向量迭代器的使用技巧和注意事项,需要的朋友参考一下 示例 begin将an返回iterator到序列容器中的第一个元素。 end返回iterator末尾的第一个元素。 如果矢量对象const,无论是begin和end返回const_iterator。如果const_iterator即使向量不返回,也要返回const,则可以使用cbegin和cend。

  • 问题内容: 我正在尝试使用SWIG为python包装一个C ++库。该库通过将 某些类型的回调函数 传递给类方法来频繁使用回调函数。 现在,在包装代码之后,我想从python创建回调逻辑。这可能吗?这是我正在尝试发现的实验..目前不起作用。 头文件和swig文件如下: paska.h: paska.i: 最后,我在python中测试.. 最后一行抛出“ TypeError:方法’handleri_

  • 在最近的一次采访中,我建议使用向量 编码过程结束后,他们说在向量上使用pair是个好主意,并要求我详细说明我之前所说的“更重”是什么意思。不幸的是,我无法详细说明。是的,我知道我们只能在一对中输入两个值,但在一个向量中可以输入更多的值,并且当向量的大小==容量等时,该向量会自动调整大小。但是我应该如何回答他们的问题?为什么具体使用<代码>向量

  • 在C语言中,在Linux上,当我用打开一个文件,然后用对其进行内存映射后,我会得到一个,我可以将其键入char*并根据需要读取。 但是,假设我想使用std::vector来访问这些数据。我怎样才能做到呢? 起初我以为我可以为我的std::vector定制一个分配器。但我看到了两个问题: 它的方法将只接收一个size参数。这是不够的,因为它还需要知道已经映射的地址,而不是分配一个新地址(就像分配器通