6

これは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 でラップされたポインターが指す同じメモリへの読み取り/書き込みアクセスが可能になります。

問題には次の 2 つの部分があると思います。

  1. A からポインターを取得する方法 (0x8c66fa0 は、ラップされたオブジェクトではなく、Swig オブジェクトを指していると思います)。
  2. メモリ ポインターと既知のデータ型を使用して、ある種の Python 配列を初期化する方法。(Numpy には frombuffer メソッドがありますが、必要と思われるのは frommemory メソッドです。) おそらく、いくつかのキャストが必要になるでしょう。

これは簡単だと思いますが、私は 1 日以上本を読んだりハッキングしたりしてきました!

2番目の部分を解決するには、例を次のように始めることができると思います:

>>> 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] が変更されるかどうかをテストします。

あなたの提案や明確な例に感謝します。

よろしく、

オーウェン

4

1 に答える 1

7

さらに読んで試してみた後、答えは次のとおりです。

1. PySwigObject A のラップされたポインタは A.__long__() として利用できます。

2. 次のように ctypes を使用して、生のポインターをインデックス可能な型にキャストできます。

ctypes のインポート
pA = ctypes.cast( A.__long__(), ctypes.POINTER( ctypes.c_uint16 ) )

次に、要素は pA[0]、pA[1] などとしてアドレス指定できます。

pA は元のオブジェクトと同じメモリを指すため、元のオブジェクトが削除された後に pA を使用しないように注意してください。

これは、問題の 2 番目の部分 (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 に変更されていることがわかります。

解決しました。:)

于 2010-02-07T03:44:30.800 に答える