2014-04-29 145 views
4

我使用了用Python编写的服务器文件来构建我的Raspberry Pi和我的iPhone之间的连接。我写了一个简单的C程序来帮助翻译莫尔斯密码。我想从Python服务器程序调用C程序中的translate()函数。从Python调用C函数

我发现了一个在线教程,跟着它的指令来写我的C程序和编辑netio_server.py文件

在我的C程序morseCodeTrans.c它就像

#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); 
}  

而且在服务器文件netio_server.py它像:

# 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 

以上是我会调用C translate()功能的唯一地方

然后我试图编译morseCodeTrans.c文件是这样的:

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

编译成功。 但是,当我跑了Python服务器程序,每当它达到线

l = morseCodeTrans.translate(tempLetter) 

刚刚终止没有任何错误信息的服务器程序。

我对Python编程非常陌生,所以我找不出问题出在哪里。任何帮助?

+4

您可能更容易使用'ctypes'模块(查看标准库中的文档)。 – wjl

+0

是的,我知道ctypes更容易使用。但现在我没有足够的时间去阅读教程,也许以后我会尝试使用ctypes。感谢您的建议。 – user3554898

回答

1

你刚刚在界面中有一些小混音。我修改了代码如下,使其工作:

#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); 
} 

它是更安全的建立与distutils,因为它可以防止无意对Python中的错误版本的链接。使用以下setup.py

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

python setup.py install只需使用。

编辑

尽管在界面中mixups,看来你的代码仍然有效。那么你的问题很可能在链接过程中。如上所述,使用distutils应该解决这个问题。如果您绝对要手动构建,请使用python-config --cflags,python-config --ldflags等,以确保您与正确版本的Python链接。

+0

嗨Stefan,谢谢你的回复。我试过编写setup.py文件并执行python setup.py安装,但是有一个错误消息说“TypeError:_init_()至少需要3个参数(给出2个)”,并且这个行被称为“module”模块扩展名('morseCodeTrans',source = ['morseCodeTrans.c'])“ – user3554898

+0

不要紧,来源= ['morseCodeTrans.c'])并解决问题。再次感谢,现在我的程序工作得很好^^ – user3554898

+0

现在好了! TypeError是由于你的输入错误:'sources - > source'。不需要向Extension()添加另一个参数。 – Stefan