2011-09-14 4 views
4

Je suis en train d'écrire un wrapper python C pour une fonction (libFunc) dont le prototype estarguments passant Python C Extension par référence

libFunc(char**, int*, char*, int) 

Comment puis-je utiliser PyArg_ParseTuple pour la mise en place des arguments pour l'appel de fonction. Voici ce que j'ai actuellement

#include <Python.h> 

    PyObject* libFunc_py(PyObject* self, PyObject* args) 
    { 
     char* input; 
     char** output; 
     int inputlen; 
     int* outputlen; 

     PyArg_ParseTuple(args, "sisi" , output, outputlen, &input, &inputlen); 


     int ret = libFunc(output, outlen, input, inputlen); 


     return Py_BuildValue("i", ret); 
    } 

Je suis capable de faire la même chose avec ctypes en utilisant byref.

+1

Voici un exemple qui utilise [Cython] (http://cython.org): [libfunc.pyx] (https://gist.github.com/cf5e036a88d1b12ea64a) – jfs

+0

Merci pour le code ... mais je n'ai pas de pyrex dans mon environnement. Pouvez-vous me dire, comment libérer la mémoire (allouée par libfunc) dans mon code ci-dessous? – Kamal

+1

1. Les utilisateurs de votre code n'ont pas besoin de Cython. Vous en avez seulement besoin pour générer des sources C pour vous. 2. Vous pouvez appeler 'free (output)' si 'libFunc()' utilise 'malloc()' pour allouer de la mémoire à 'output'. 3. s/outlen/outputlen/ – jfs

Répondre

0

Je fini par le faire de cette façon

#include <Python.h> 

    PyObject* libFunc_py(PyObject* self, PyObject* args) 
    { 
     char* input; 
     char* output; 
     int inputlen; 
     int outputlen; 

     PyArg_ParseTuple(args, "s#" , &input, &inputlen); 


     int ret = libFunc(&output, &outlen, input, inputlen); 

     if (ret !=0) 
     { 
      Py_ErrSetString(PyExc_RunTimeError, "ErrorMessage"); 
      return NULL; 
     } 

     PyObject* retStr = Py_BuildValue("s#", output,outputlen); 

     if(output) 
      free(output) 

     return retStr; 
    } 
+2

1. 'if (! PyArg_ParseTuple (...)) renvoie NULL;' 2. Vous pouvez utiliser ['{PyErr_SetString (PyExc_RuntimeError," Message d'erreur "); return NULL; } '] (http://www.google.com/codesearch#search/&q=PyErr_SetString\%28PyExc_RuntimeError&type=cs) au lieu de' return Py_BuildValue ("s #", "Error", 5) '. – jfs

Questions connexes