2014-04-29 4 views
4

J'ai utilisé un fichier serveur qui a été écrit en Python pour créer une connexion entre mon Raspberry Pi et mon iPhone. Et j'ai écrit un simple programme C qui aide à traduire le code morse. Je veux appeler la fonction translate() dans le programme C à partir du programme serveur Python.Appel de la fonction C à partir de Python

J'ai trouvé un tutoriel en ligne et suivi ses instructions pour écrire mon programme C et éditer le fichier netio_server.py

Dans mon programme C morseCodeTrans.c c'est comme

#include <Python.h> 
#include <stdio.h> 

static PyObject* py_translate(PyObject* self, PyObject* args) 
{ 
char *letter; 
PyArg_ParseTuple(args, "s", &letter); 

if(strcmp(letter, ".-") == 0) 
    return Py_BuildValue("c", 'A'); 
else if(strcmp(letter, "-...") == 0) 
    return Py_BuildValue("c", 'B'); 
... 

} 

static PyMethodDef morseCodeTrans_methods[] = { 
    {"translate", py_translate, METH_VARARGS}, 
    {NULL, NULL} 
}; 

void initmorseCodeTrans() 
{ 
    (void)Py_InitModule("morseCodeTrans", morseCodeTrans_methods); 
}  

Et dans le fichier du serveur netio_server.py il est comme:

# other imports 
import morseCodeTrans 

... 

tempLetter = '' 

if line == 'short': 
    tempLetter += '.' 
elif line == 'long': 
    tempLetter += '-' 
elif line == 'shortPause': 
    l = morseCodeTrans.translate(tempLetter) 
    print "The letter is", l 

au-dessus est le seul endroit que je qualifierais la fonction C translate()

J'ai ensuite essayé de compiler le fichier morseCodeTrans.c comme ceci:

gcc -shared -I/usr/include/python2.7/ -lpython2.7 -o myModule.so myModule.c 

La compilation a réussi. Mais quand je courais le programme serveur Python, chaque fois qu'il a atteint la ligne

l = morseCodeTrans.translate(tempLetter) 

Le programme serveur vient de se terminer sans message d'erreur. Je suis très nouveau dans la programmation Python, donc je ne pouvais pas savoir où est le problème. De l'aide?

+4

Vous pourriez avoir un temps plus facile avec le module 'ctypes' (regardez la documentation de la bibliothèque standard). – wjl

+0

Oui, je sais que ctypes est plus facile à utiliser. Mais maintenant je n'ai pas assez de temps pour passer par le tutoriel, peut-être que plus tard j'essaierai d'utiliser les ctypes. Merci pour la suggestion. – user3554898

Répondre

1

Vous venez d'avoir quelques mixages mineurs dans l'interface. J'ai modifié le code comme suit pour le faire fonctionner:

#include <Python.h> 
#include <stdio.h> 

static PyObject* py_translate(PyObject* self, PyObject* args) 
{ 
    char *letter; 
    PyArg_ParseTuple(args, "s", &letter); 

    if(strcmp(letter, ".-") == 0) 
    return Py_BuildValue("c", 'A'); 
    else if(strcmp(letter, "-...") == 0) 
    return Py_BuildValue("c", 'B'); 
    /* ... */ 
    else 
    Py_RETURN_NONE; 
} 

static PyMethodDef morseCodeTrans_methods[] = { 
    {"translate", py_translate, METH_VARARGS, ""}, 
    {0} 
}; 

PyMODINIT_FUNC initmorseCodeTrans(void) 
{ 
    Py_InitModule("morseCodeTrans", morseCodeTrans_methods); 
} 

Il est beaucoup plus sûr de construire avec distutils, car il vous empêche de relier accidentellement contre de mauvaises versions Python. Utilisez les commandes suivantes setup.py:

from distutils.core import setup, Extension 
module = Extension('morseCodeTrans', sources=['morseCodeTrans.c']) 
setup(ext_modules=[module]) 

utiliser simplement comme python setup.py install.

Modifier

Malgré les mixups dans l'interface, il semble que votre code fonctionne toujours. Ensuite, votre problème est le plus probable lors de la liaison. Comme mentionné ci-dessus, en utilisant distutils devrait remédier à cela. Si vous voulez absolument construire manuellement, utilisez python-config --cflags, python-config --ldflags etc pour vous assurer que vous faites un lien avec la bonne version de Python.

+0

Salut Stefan, merci pour votre réponse. J'ai essayé d'écrire le fichier setup.py et de faire python setup.py install, mais il y a un message d'erreur dit "TypeError: _init_() prend au moins 3 arguments (2 donnés)" et qui a été renvoyé à cette ligne "module = Extension ('morseCodeTrans', source = ['morseCodeTrans.c']) " – user3554898

+0

Peu importe, je viens d'ajouter un autre paramètre à Extension(): Extension (morseCodeTrans, library_dirs = ['/ usr/local/include'], sources = ['morseCodeTrans.c']) et le problème a été résolu.Merci encore, maintenant mon programme fonctionne parfaitement bien ^^ – user3554898

+0

Bon que ça marche maintenant! Le 'TypeError' était dû à votre faute de frappe:' sources -> source'. Pas besoin d'ajouter un autre paramètre à 'Extension()'. – Stefan

Questions connexes