从Python调用C函数

4 投票
1 回答
1286 浏览
提问于 2025-04-18 04:42

我使用了一个用Python写的服务器文件,来建立我的树莓派和我的iPhone之间的连接。同时,我写了一个简单的C程序,用来翻译摩尔斯电码。我想从Python服务器程序中调用C程序里的translate()函数。

我在网上找到一个教程,按照它的步骤写了我的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编程很陌生,所以我不知道问题出在哪里。有没有人能帮帮我?

1 个回答

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就可以了。

补充说明

尽管界面上有些混乱,但看起来你的代码还是能正常工作的。那么你遇到的问题很可能是在链接的时候。正如上面提到的,使用distutils应该能解决这个问题。如果你真的想手动构建,可以使用python-config --cflagspython-config --ldflags等命令,确保你链接的是正确版本的Python。

撰写回答