2014-04-29 188 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