在 Python 中,如何访问由 SWIG 包装的 uint16[3] 数组(即解开 PySwigObject)?

StackOverflow https://stackoverflow.com/questions/2209395

  •  18-09-2019
  •  | 
  •  

这是Python问题。我有一个变量A

>>> A
<Swig Object of type 'uint16_t *' at 0x8c66fa0>

>>> help(A)
class PySwigObject(object)
  Swig object carries a C/C++ instance pointer

A 引用的实例是一个连续数组 uint16[3],问题是从 Python 访问该数组。

在Python中,如何创建一个长度为3的变量B,它使我可以读/写访问A中包装的指针所指向的同一内存?

我认为问题有两部分:

  1. 如何从A中取出指针。(我认为 0x8c66fa0 指向 Swig 对象,而不是包装的对象)。
  2. 如何使用内存指针和已知数据类型初始化某种 Python 数组。(Numpy 有一个 frombuffer 方法,但似乎需要的是一个 frommemory 方法。)也许需要一些转换。

我认为这应该很容易,但我已经阅读和破解了一天多了!

为了解决第二部分,我认为可以这样开始一个例子:

>>> import numpy
>>> C = numpy.ascontiguousarray([5,6,7],"uint16")
>>> C
array([5, 6, 7], dtype=uint16)
>>> C.data
<read-write buffer for 0x8cd9340, size 6, offset 0 at 0x8902f00>

然后尝试使用“0x8902f00”和“uint16”构建 B(任何向量类型),并测试更改 B[2] 是否会导致 C[2] 发生更改。

非常感谢您的建议或明确的例子。

问候,

欧文

有帮助吗?

解决方案

经过更多阅读和尝试,答案如下:

1. The wrapped pointer in PySwigObject A is available as  A.__long__() .

2. A raw pointer can be cast into an indexable type using ctypes as follows

import ctypes
pA = ctypes.cast( A.__long__(), ctypes.POINTER( ctypes.c_uint16 ) )

然后元素可以被寻址为 pA[0]、pA[1] 等

pA与原对象指向同一块内存,因此要注意原对象被删除后不要再使用pA。

这是问题第二部分的示例(在 Python 中使用已知类型的原始指针),

C = numpy.ascontiguousarray([5,6,7],"uint16")  # make an array
C
rawPointer = C.ctypes.data
pC = ctypes.cast( rawPointer, ctypes.POINTER( ctypes.c_uint16 ))
pC[0:3]
pC[1]=100
pC[0:3]
C

在Python中运行该示例将显示C[1]和pC[1]都已更改为100。

解决了。:)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top