11
votes

Swig C-to-Python Int Array

J'essaie d'accéder à une fonction C avec le prototype suivant de Python à l'aide de Swig: xxx pré>

Swig crée le .so sans problèmes et je peux l'importer en python, mais quand je Essayez d'y accéder avec les suivants: P>

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: in method 'cosetCoding', argument 4 of type 'int *'


0 commentaires

3 Réponses :


2
votes

Vous devez construire un tableau de C_int code> pour que cela fonctionne: xxx pré>

mis à jour strong> Ajout d'un exemple plus complet. J'utilise CTTYPES version 1.1.0 sous Python 2.6; Peut-être que nous faisons quelque chose de légèrement différemment? p>

Peut-être laissez-passer ctypes.byref (arr) code> à la place? p>

% python test_coset.py
cellFailure: 1 2


4 commentaires

Même erreur qu'Arvée ... ARR est un: <__ Main Main __. Objet C_INT_ARRAY_8 AT 0X7FDB9DA9AD40> Pas un 'int *'


J'ai donc essayé de passer à CTTYPES de Swig, et cela importera le .so et Python ne se plaignent pas de transmettre les paramètres, mais de renvoyer la mauvaise valeur de la fonction. J'ai essayé cela sur une autre fonction et il y avait le même résultat (sortie incorrecte).


Grattez cela, le problème est avec mon programme C apparemment pour la fonction COSETCODING. Donc cela fonctionne! Yay! Merci! Ma fonction qui retourne un double retourne toujours des ordures (assez étrangement).


@Adam génial d'entendre que vous faites des progrès!



14
votes

Utilisez CTYPES si vous le pouvez. C'est plus simple. Cependant, depuis que vous avez demandé Swig, ce dont vous avez besoin est une type décrivant comment gérer l'INT *. Swig ne sait pas combien de nombres entiers peuvent être signalés. Ci-dessous est piraté à partir d'un exemple de la documentation de Swig sur Typemaps multi-arguments :

%typemap(in) (const int memoryCells, int *cellFailure) {
  int i;
  if (!PyList_Check($input)) {
    PyErr_SetString(PyExc_ValueError, "Expecting a list");
    return NULL;
  }
  $1 = PyList_Size($input);
  $2 = (int *) malloc(($1)*sizeof(int));
  for (i = 0; i < $1; i++) {
    PyObject *s = PyList_GetItem($input,i);
    if (!PyInt_Check(s)) {
        free($2);
        PyErr_SetString(PyExc_ValueError, "List items must be integers");
        return NULL;
    }
    $2[i] = PyInt_AsLong(s);
  }
}

%typemap(freearg) (const int memoryCells, int *cellFailure) {
   if ($2) free($2);
}


2 commentaires

Essayé cela avec Swig, fonctionne bien. Merci! Comme il y a 3 réponses, je suppose que je devrais utiliser CTTYPES, bien que je puisse passer à cela dans un proche avenir.


Pas besoin de coder les Typemaps à la main si vous utilisez numpy.i , vois ma réponse.



8
votes

Marque a raison, vous aurez besoin d'une tympapes. Cependant, il n'est pas nécessaire de coder le type de code à la main si vous utilisez numpy.i code> (http://docs.scipy.org/doc/numpy/reefer/swig.interface-file.html), qui définit déjà les typaps nécessaires pour activer C en matrices numpues et vice versa.

Dans votre cas (en supposant CellFailure code> est un tableau d'entrée) Vous voudrez utiliser P>

from numpy import asarray
cosetCoding.cosetCoding(10,11,asarray([0,0,0,0,0,0,0,0]),0)


1 commentaires

Cool, je viens de commencer à utiliser Numpy récemment. Beaucoup plus facile.