2017-03-26 3 views
0

配列の値を変更したいC関数にnumpy配列を渡そうとしています。しかし、正しく動作させるためには、インデックスを2倍しなければなりません。奇数インデックスに値を代入すると(iとする)、インデックス(i-1)/2にゴミが割り当てられます。ここにソースコードがあります。numpy配列がC関数によって変更されているときにマジックが起こっています

C:

#include "assign_array.h" 

void assign(int *arr, int i) { 
    arr[i] = 2017; 
} 

のPython:

import ctypes, numpy 
lib2 = ctypes.cdll.LoadLibrary('./assign_array.so') 
for i in range(5): 
    array = numpy.zeros(8, dtype = int) 
    ptr = array.ctypes.data_as(ctypes.POINTER(ctypes.c_int)) 
    print('i = {}:'.format(i)) 
    lib2.assign(ptr, i) 
    print(array) 

Screenshot

ですが、なぜでしょうか?

答えて

1

それは正確ごみではありません:20470x7e1で、86629490360320x7E100000000です。異なるCコンパイラ(またはCコンパイラに提供されるフラグ)を混在させているように見えるので、intは64ビットだとPythonは信じていますが、Cコンパイラはintが32ビットだと考えています。実際には、Pythonのintは、Cコンパイラではintと一致するとは限りません。より一般的にはlongと一致する可能性があります。

the numpy documentationによれば、dtypeは、numpy.int32と指定することができ、具体的には32ビットのintを指定することができます。これを扱う最も簡単な方法かもしれません。もちろん、Cコードをlongに変更することもできます(Cコンパイラの設定では、64ビットlongと仮定します)。

+0

これをコンパイルします: 'gcc -shared -o assign_array.so -fPIC assign_array.c' – Dimansel

+0

Linux/Unix-ishシステムを使用していることを示唆していますが、内部の 'int'型に' long 'を使用し、ベースのCコンパイラは64ビットの' long'を持っています。他のCコンパイラも同様です。 – torek

+1

@MatteoItalia:括弧内の更新を参照してください。Python 'int'はC' long'にマップされる可能性が最も高いです。 (それは64ビットの 'int'がまれであることは事実です; Crayはそれらのシステムの1つでした) – torek

関連する問題