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

SWIG / python数组内部结构

翟俊名
2023-03-14
问题内容

我在header.h内部定义了一个结构,如下所示:

typedef struct {
....
    int      icntl[40];
    double   cntl[15];
    int      *irn, *jcn;
....

当我用这种结构初始化一个对象时,我可以访问整数/双精度数,但不能访问数组。

>> st.icntl
<Swig Object of type 'int *' at 0x103ce37e0>
>> st.icntl[0]
Traceback (most recent call last):
  File "test_mumps.py", line 19, in <module>
    print s.icntl[0]
TypeError: 'SwigPyObject' object is not subscriptable

如何访问读/写中的值?


问题答案:

最简单的方法是将数组包装在内struct,然后可以提供额外的方法来满足“可订阅”的要求。

我整理了一个小例子。假定您使用的是C ++,但是从中构造等效的C版本相当简单,它只需要重复一些即可。

首先,具有struct要包装的C ++头文件和用于包装固定大小数组的模板:

template <typename Type, size_t N>
struct wrapped_array {
  Type data[N];
};

typedef struct {
    wrapped_array<int, 40> icntl;
    wrapped_array<double, 15> cntl;
    int      *irn, *jcn;
} Test;

我们相应的SWIG界面如下所示:

%module test

%{
#include "test.h"
#include <exception>
%}

%include "test.h"
%include "std_except.i"

%extend wrapped_array {
  inline size_t __len__() const { return N; }

  inline const Type& __getitem__(size_t i) const throw(std::out_of_range) {
    if (i >= N || i < 0)
      throw std::out_of_range("out of bounds access");
    return self->data[i];
  }

  inline void __setitem__(size_t i, const Type& v) throw(std::out_of_range) {
    if (i >= N || i < 0)
      throw std::out_of_range("out of bounds access");
    self->data[i] = v;
  }
}

%template (intArray40) wrapped_array<int, 40>;
%template (doubleArray15) wrapped_array<double, 15>;

诀窍在于,我们曾经%extend提供过__getitem__Python用于下标读取和__setitem__写入的内容。(我们也可以提供一个__iter__使它可迭代的类型)。我们还给出了wraped_array要使用唯一名称的特定s,以使SWIG将它们包装在输出中。

使用提供的接口,我们现在可以执行以下操作:

>>> import test
>>> foo = test.Test()
>>> foo.icntl[30] = -654321
>>> print foo.icntl[30]
-654321
>>> print foo.icntl[40]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "test.py", line 108, in __getitem__
    def __getitem__(self, *args): return _test.intArray40___getitem__(self, *args)
IndexError: out of bounds access

您可能还会发现这种方法很有用/有趣,可以作为替代方法。



 类似资料:
  • 问题内容: 我正在尝试使用swig从python使用以下原型访问C函数: Swig创建.so没问题,我可以将其导入python,但是当我尝试使用以下命令进行访问时: 我得到以下回溯: 该指针应该是一个int数组,其大小由memoryCells定义 问题答案: 如果可以,请使用ctypes。更简单。但是,由于您要求输入SWIG,因此需要的是一个描述如何处理int *的类型图。SWIG不知道可以指向多

  • CInode CInode 包含某一文件的元数据,每个文件都有一个 CInode 。它存储着类似谁拥有这个文件、此文件有多大这样的信息。 CDentry CDentry 用于把索引节点和文件(或目录)名关联到一起。一个 CDentry 最多可链接到一个 CInode (也可以不链接任何 CInode ),一个 CInode 可被多个 CDentry 链接。 CDir CDir 仅存在于目录索引节点

  • 这不是 linux-insides 中的一般章节。正如你从题目中理解到的,它主要描述 Linux 内核中的内部系统数据结构。比如说,中断描述符表 (Interrupt Descriptor Table), 全局描述符表 (Global Descriptor Table) 。 大部分信息来自于 Intel 和 AMD 官方手册。

  • 问题内容: 我在python代码中发现了瓶颈,并与psycho等打交道。然后决定编写ac / c ++扩展以提高性能。 借助swig,您几乎不需要关心参数等。一切正常。 现在我的问题是:swig创建了一个很大的py文件,该文件在调用实际的.pyd或.so代码之前会执行很多“检查”和“ PySwigObject”。 你们中的任何人是否有经验,如果您手动编写此文件或让wig来做,是否可以获得更多性能。

  • 我们可以在定义ThreadPoolExecutors的同时提供BlockingQueue实现。但是,如果我使用工厂(Executors)创建一个单线程池,如下所示,我想知道使用的是哪一个阻塞队列。我猜这是一个LinkedBlockingQueue。文档谈到了无界队列,但没有揭示实现。

  • 问题内容: 我试图弄清楚需要更改什么SWIG接口文件才能处理getFoo返回一个指向自定义结构数组(sender_id_t)的指针。没有任何特殊的SWIG接口代码,我只得到Java端的指针。如何将指针转换为可以循环或迭代的内容(在Java中),以便获取每个sender_id_t id值?感谢任何建议。 C结构: C函数: 例外: 问题答案: 最简单的解决方案不涉及编写任何JNI,实际上是方法2。因