2017-03-26 3 views
0

J'essaie de passer un tableau numpy dans la fonction C où je veux changer les valeurs du tableau. Mais je dois multiplier l'index par 2 pour le faire fonctionner correctement. L'attribution d'une valeur à un index impair (que ce soit i) conduit à affecter une poubelle à l'index (i-1)/2. Voici le code source.La magie se produit lorsque le tableau numpy est en train de changer par la fonction 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

Pourquoi est-ce qui se passe?

Répondre

1

Ce n'est pas exactement déchets: 2047 est 0x7e1 et 8662949036032 est 0x7E100000000. Il semble que vous mélangez différents compilateurs C (ou drapeaux fournis aux compilateurs C), de sorte que Python pense que int est 64 bits, mais votre compilateur C pense que int est de 32 bits. Bien que, en fait, int en Python n'est pas garanti pour correspondre int dans un compilateur C; il pourrait plus généralement correspondre long.

Selon the numpy documentation, dtype peut être spécifié comme numpy.int32 de se référer spécifiquement à un 32 bits int. Cela pourrait être la méthode la plus simple de traiter cela, ou bien sûr vous pouvez changer le code C pour utiliser long (en supposant que long s dans les paramètres de votre compilateur C).

+0

Je compile de cette façon: 'gcc -shared -o assign_array.so -fPIC assign_array.c' – Dimansel

+0

Cela suggère (bien que cela ne prouve pas) que vous utilisez un système Linux/Unix-ish, donc probablement votre base Python utilise C 'long' pour son type interne' int', et votre compilateur C de base a 'long' de 64 bits. Les autres compilateurs C sont similaires. – torek

+1

@MatteoItalia: voir mise à jour avec parenthetical: Python 'int' est très probablement mappé à C' long'. (Il est vrai que 64 bits 'int' est rare, Cray était l'un de ces systèmes.) – torek