2014-07-25 34 views
1

我試圖對Python做一個C擴展。我的問題是,我有C函數內的C函數,我做了一個C擴展。例如,我在這些C函數中使用pmd.h和usb1024LS.h中的C函數。當我嘗試運行我的腳本時,出現「undefined symbol:hid_init」等錯誤。 hid_init是一個函數。 我曾嘗試在c主程序中運行該程序,並且它可以正常工作。 如何從具有擴展名的其他C函數內部調用C函數?在Python的C擴展中調用C函數

謝謝!

我的代碼: test.py - 測試腳本:

import ctypes 
import myTest_1024LS 

ctypes_findInterface = ctypes.CDLL('/home/oysmith/NetBeansProjects/MCCDAQ/usb1024LS_with_py/myTest_1024LS.so').findInterface 
ctypes_findInterface.restype = ctypes.c_void_p 
ctypes_findInterface.argtypes = [ctypes.c_void_p] 

ctypes_findInterface() 

setup.py:

from distutils.core import setup, Extension 

setup(name="myTest_1024LS", version="0.0", ext_modules = [Extension("myTest_1024LS", ["myTest_1024LS.c"])]) 

myTest_1024LS.c:

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <ctype.h> 
#include <sys/types.h> 
#include <asm/types.h> 
#include <python2.7/Python.h> 

#include "pmd.h" 
#include "usb-1024LS.h" 
#include "myTest_1024LS.h" 

void findInterface(void){ 
int interface; 
hid_return ret; 
ret = hid_init(); 
if (ret != HID_RET_SUCCESS) { 
     fprintf(stderr, "hid_init failed with return code %d\n", ret); 
     exit(1); 
} 

if ((interface = PMD_Find_Interface(&hid, 0, USB1024LS_PID)) >= 0) { 
     printf("USB 1024LS Device is found! interface = %d\n", interface); 
} else if ((interface = PMD_Find_Interface(&hid, 0, USB1024HLS_PID)) >= 0) { 
     printf("USB 1024HLS Device is found! interface = %d\n", interface); 
} else { 
     fprintf(stderr, "USB 1024LS and USB 1024HLS not found.\n"); 
     exit(1); 
} 
} 

PyDoc_STRVAR(myTest_1024LS__doc__, "myTes_1024LS point evaluation kernel"); 
PyDoc_STRVAR(findInterface__doc__, "find device"); 

static PyObject *py_findInterface(PyObject *self, PyObject *args); 

static PyMethodDef wrapper_methods[] = { 
{"findInterface", py_findInterface, METH_VARARGS, findInterface__doc__}, 
{NULL, NULL} 
}; 

PyMODINIT_FUNC initwrapper(void){ 
Py_InitModule3("wrapper", wrapper_methods, myTest_1024LS__doc__); 

} 

static PyObject *py_findInterface(PyObject *self, PyObject *args){ 

if(!PyArg_ParseTuple(args, "")){ 
    return NULL; 
} 
findInterface(); 
return 0; 
} 
+0

你想運行一個Python腳本調用C函數,然後將再次調用Python函數?如果我說得對:如何重寫C中的內部Python函數?畢竟,我想你想通過切換到C(可能是速度?)來達到某種程度,然後再回到Python可能會破壞這種樂趣。 – Alfe

+0

不,我有一個Python腳本調用C函數,調用另一個C函數,就像你在myTest_1024LS.c中看到的一樣。 C函數內部的C函數調用是對USB設備驅動程序的調用。我不想爲所有驅動程序函數編寫C語言,因爲它們中有很多。 –

+0

我明白了。您是如何照顧USB驅動程序所需的庫鏈接到您的代碼的? – Alfe

回答

2

在構建C擴展其本身必須鏈接到其他共享庫,你必須告訴哪些鏈接setup.py。在這種情況下,至少要導出hid_init()函數庫。有關更多詳細信息和示例,請參閱Python文檔:Building C and C++ Extensions with distutils。第二個示例包含將一個額外的庫鏈接到擴展模塊的參數。


的​​「聲明」是錯誤的:void是不一樣的一個空指針(void*)。該findInterface() C函數既沒有參數也沒有返回值,這是「申報」爲:

ctypes_findInterface.argtypes = [] 
ctypes_findInterface.restype = None