2013-04-05 77 views
2

Python列表我得到了,我可以得到它的指針,並通過該指針,指向C++ Python列表上修改從C++

MyPointer = TheList.as_pointer() 

工作,現在我這個地址傳遞給C++與ctypes的

在C++中,我可以做到以下幾點:

*(float*) MyPointer = 2.0f; //for example 

和Python的值將立刻更新,現在的問題是: 如何擴展或刪除一些值(如修改列表直接LY從C++) 因爲我感覺這些數據是一個std::vector怎麼辦push_back等具有快速的方式來調整大小(如迭代在Python是非常慢)

+1

'as_pointer'似乎是Blender的特定據我可以看到... ...總之,一個Python'list'是*不*實現爲'的std ::矢量',這是一個自己的數據結構。您需要將指針轉換爲該數據類型才能使用它。該類型在[Python C API](http://docs.python.org/2/c-api/)中定義。 – 2013-04-05 12:24:13

+0

當你想使用Python C-API時,你最好寫一個C擴展模塊,而不是使用ctypes,參見http://docs.python.org/2.7/extending/index.html和http:// docs。 python.org/2.7/c-api/list.html – 2013-04-05 12:25:48

+0

@KonradRudolph真正來自Blender Python api :) – 2013-04-05 12:30:43

回答

4

鑑於只有指針,你不能延長名單。你傳遞給C++的是內部用於實現Python列表的數組的地址。這不能是std::vector,因爲Python列表不是作爲STL向量實現的,而是作爲Python對象引用的C級數組實現的。這些數組不包含指向Python列表對象的反向指針。

要改變列表,請看the documentation並將您的C++代碼與Python庫鏈接。如果你真的必須從ctypes中調用你的C++函數,請使用列表中的id來調用它,以獲得指向列表的指針,而不是它的元素數組。然後,你可以在列表像這樣進行操作:

#include <Python.h> 

extern "C" 
void append_to_list(uintptr_t lst_id) 
{ 
    PyObject* lst = reinterpret_cast<PyObject*>(ptr); 
    PyObject* new_num = PyFloat_FromDouble(2.0); 
    if (!new_num) { 
     ... PyFloat creation failed ... 
    } 
    int ret = PyList_Append(lst, new_num); 
    Py_DECREF(new_num); 
    if (ret) { 
     ... PyList_Append failed ... 
    } 
} 
+0

我理解這個概念,但它給了我在python中讀取內存錯誤時的情況:在0x000處讀取訪問衝突 – 2013-04-05 12:40:33

+0

它在PyList_Append上失敗 – 2013-04-05 12:53:34

+0

沒有進行錯誤檢查,但是在每行之後沒有printf,並且在PyList_Append – 2013-04-05 13:04:22