web-dev-qa-db-fra.com

Comment convertir une liste Python en un tableau C en utilisant ctypes?

Si j'ai les 2 séries de code suivantes, comment puis-je les coller?

void
c_function(void *ptr) {
    int i;

    for (i = 0; i < 10; i++) {
        printf("%p", ptr[i]);
    }

    return;
}


def python_routine(y):
    x = []
    for e in y:
        x.append(e)

Comment puis-je appeler la fonction c_function avec une liste d'éléments contigus dans x? J'ai essayé de convertir x en c_void_p, mais cela n'a pas fonctionné. 

J'ai aussi essayé d'utiliser quelque chose comme 

x = c_void_p * 10 
for e in y:
    x[i] = e

mais cela génère une erreur de syntaxe. 

Le code C veut clairement l'adresse d'un tableau. Comment puis-je arriver à cela?

37

Le code suivant fonctionne sur des listes arbitraires:

import ctypes
pyarr = [1, 2, 3, 4]
arr = (ctypes.c_int * len(pyarr))(*pyarr)
67
Gabi Purcaru

De le tutoriel ctypes :

>>> IntArray5 = c_int * 5
>>> ia = IntArray5(5, 1, 7, 33, 99)
8
Ryan Ginstrom

Ceci est une explication de la réponse acceptée.

ctypes.c_int * len(pyarr) crée un tableau (séquence) de type c_int de longueur 4 ( python3 , python 2 ). Puisque c_int est un objet dont le constructeur utilise un argument, (ctypes.c_int * len(pyarr)(*pyarr) effectue une initiation unique de chaque instance c_int à partir de pyarr. Un plus facile à lire form est:

pyarr = [1, 2, 3, 4]
seq = ctypes.c_int * len(pyarr)
arr = seq(*pyarr)

Utilisez la fonction type pour voir la différence entre seq et arr.

6
akhan
import ctypes
import typing

def foo(aqs : typing.List[int]) -> ctypes.Array:
    array_type = ctypes.c_int64 * len(aqs)
    ans = array_type(*aqs)
    return ans

for el in foo([1,2,3]):
    print(el)

cela donnera:

1
2
3
0
Jörg Beyer