2017-07-21 24 views
4

我有用於包括類似功能的裝置的C庫:Python擴展用C - 通過列出來回

int GetDevInfo(int *devices); 

在這種情況下,設備是可能已經定義這樣一個整數數組:

int devices[10] 

該函數將通過硬件總線循環查找活動設備。發現它們時,它會將設備號碼放入devices[]中的下一個可用點。因此,例如掃描前:

devices = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}和全局變量DeviceCount知道有0個活動的。該功能發揮了神奇的作用,並決定設備5和8處於活動狀態。所以後來:

devices = {5, 8, 0, 0, 0, 0, 0, 0, 0, 0}DeviceCount知道有2

我想Python的功能是這樣的:

devices = list(range(64)) 
for i in range(0,len(devices)): # Set them all to 0 
    devices[i] = 0 
DeviceCount = 0 

# Now we'll update it 
DeviceCount = myModule.GetDevInfo(DeviceCount, devices) 

當它返回,DeviceCount可能被設置爲2,和設備的外觀像:

[5, 8, 0, 0, 0, 0, 0, 0, 0, 0] 

我已經寫了代碼爲其他包裝傳入整數並傳回字符串,但我沒有找到紐約網絡智慧來幫助我。我知道,如果我做這樣的事情:

def f(a, data): 
    a.append(data) 

l = [1, 2, 3] 
f(l, 4) 

我得到l=[1, 2, 3, 4]但它並不明顯如何得到一個Python的包裝,效果C.

Thannks提前,並且還有披薩的錢在裏面,任何人都可以幫忙!

回答

0

好吧,閱讀網頁和大量的試驗和錯誤後的...

static PyObject* LMS_module_timesTwo(PyObject *self, PyObject *args) 
{ 
    int i, numLines; 
    PyObject *listObj, *numObj; 
    unsigned int n; 

    n = PyTuple_Size(args); 
    if (1 == n) { 
    /* argument 1 should be an list of integers */ 
    listObj = PyTuple_GetItem(args, 0); 
    /* get the number of elements in the list */ 
    numLines = PyList_Size(listObj); 

    /* should raise an error here. */ 
    if (numLines < 0) return NULL; /* Not a list */ 

    for (i=0; i<numLines; i++) { 
     numObj = PyList_GetItem(listObj, i); 
     n = PyLong_AsUnsignedLong(PyNumber_Long(numObj)); 
     // This is the action - multiply by 2 for the test case 
     n = n * 2; 
     PyList_SetItem(listObj, i, Py_BuildValue("i", n)); 
    } 
    } else { 
     PyErr_SetString(PyExc_ValueError, "Function expects one argument"); 
     return NULL; 
    } 
    return PyLong_FromLong(1); 
} 

與該代碼作爲擴展的一部分(我離開了其他結構位,但可以張貼如果有人整件事需要它們),並且這是一個Python 3測試程序,它的工作效果非常好!

import my_module 

    testlist = [1, 2, 3, 4, 5] 
    print("List before multiplying = ",testlist) 
    my_module.timesTwo(testlist) 
    print("List after multiplying = ",testlist) 

非常感謝任何閱讀過這篇文章並思考過答案的人。我的實際代碼也有錯誤檢查和內容,我不關心如果程序通過垃圾會發生什麼,因爲這是一個非常特殊的功能。

問題最初提出它作爲傳遞一個列表作爲數組到C函數,所以這是更接近最終:

static PyObject* LMS_module_timesTwo(PyObject *self, PyObject *args) 
{ 
    int i, numLines; 
    PyObject *listObj, *numObj; 
    unsigned int n; 
    unsigned int carray[64]; // this has to be big enough! 

    n = PyTuple_Size(args); 
    if (1 == n) { 
    /* argument 1 should be an list of integers */ 
    listObj = PyTuple_GetItem(args, 0); 
    /* get the number of elements in the list */ 
    numLines = PyList_Size(listObj); 

    /* should raise an error here. */ 
    if (numLines < 0) return NULL; /* Not a list */ 

    for (i=0; i<numLines; i++) { 
     numObj = PyList_GetItem(listObj, i); 
     carray[i] = PyLong_AsUnsignedLong(PyNumber_Long(numObj)); 
    } 
    /* Do the actual work on the array */ 
    someCfunction(carry); // this modifies the array somehow 
    for (i=0; i<numLines; i++) { 
     PyList_SetItem(listObj, i, Py_BuildValue("i", carray[i])); 
    } 
    } else { 
     PyErr_SetString(PyExc_ValueError, "Function expects one argument"); 
     return NULL; 
    } 
    return PyLong_FromLong(1); 
}