我一直在网上搜索,但没找到。我有以下Python代码:
class LED(Structure):
_fields_ = [
('color', c_char_p),
('id', c_uint32)
]
class LEDConfiguration(Structure):
_fields_ = [
('daemon_user', c_char_p),
('leds', POINTER(LED)),
('num_leds', c_uint32)
]
下面是一个使用这些结构并返回LEDConfiguration的简化示例函数。在
^{pr2}$现在这是我使用的C代码(我已经去掉了设置python/调用“parseLedConfiguration”函数/etc所涉及的所有内容,但是如果有帮助的话,我可以添加进来)。在
/*Calling the python function "parseLedConfiguration"
pValue is the returned "LEDConfiguration" python Structure*/
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pValue != NULL)
{
int i, num_leds;
PyObject *obj = PyObject_GetAttr(pValue, PyString_FromString("daemon_user"));
daemon_user = PyString_AsString(obj);
Py_DECREF(obj);
obj = PyObject_GetAttr(pValue, PyString_FromString("num_leds"));
num_leds = PyInt_AsLong(obj);
Py_DECREF(obj);
obj = PyObject_GetAttr(pValue, PyString_FromString("leds"));
PyObject_Print(obj, stdout, 0);
我的问题是如何获取返回到最终“obj”的内容。“obj”上的“PyObject_Print”显示以下输出:
<ConfigurationParser.LP_LED object at 0x7f678a06fcb0>
我想进入一种状态,在这种状态下,我可以用访问上述“LEDConfiguration”对象的方式访问LP_-LED对象。在
编辑1
我想另一个可能更重要的问题是,我的python代码正确吗?这就是我应该如何将“Structure”的列表或数组存储在另一个“Structure”中,以便可以从pythoncapi访问它吗?在
谢谢!在
既然你的编辑1澄清了潜在的问题,让我把它放在首位:
不,这就是您应该如何将
Structure
数组存储在另一个Structure
中,以便可以从non-Python-C-API
C代码中访问它。如果希望从pythoncapi访问它,只需使用Pythonlist
。在一般来说,如果你同时用Python和C编写代码,那么只有一方必须向后弯曲才能与另一方协同工作。在Python中使用
ctypes
Structure
s和POINTER
s等的目的是允许它们直接在C中工作,而不必经过C API。相反,使用PyList_GetItem
这样的函数的目的是允许您使用普通的Python代码,而不是ctypes
Python代码。在因此,如果您想将
list
存储在要通过pythoncapi访问的Structure
中,只需存储一个Pythonlist
-而且您实际上一开始就不需要Structure
;使用普通的Python类(可能与__slots__
一起使用)。您完全可以不导入ctypes
来编写此代码。在相反,如果您想存储可以直接在C中使用的结构,可以使用}内部,就不再需要PythonAPI了,因为结构都是C的。当您有了现有的C代码并希望与之交互时,通常就是这样而不是从头开始设计C代码,但是没有规则表明不能用其他方式使用它。在
ctypes
;然后,在C代码中,一旦您进入PyObject *
的{同时,如果这是您第一次尝试编写相互通信的C和Python代码,我建议您使用}来与对Python一无所知的C代码进行对话。然后,第三个项目使用C API与Python代码进行对话,而Python代码对
Cython
。然后,一旦您熟悉了这一点,如果您想学习ctypes
,那么可以做一个不同的项目,使用Python和{ctypes
(与大多数C扩展模块一样)一无所知。一旦你熟悉了这三种方法,你就可以为将来的大多数项目选择合适的一种。在现在,回答具体问题:
首先,当
PyList_GetItem
(或C API中的大多数其他函数)返回NULL时,这意味着存在异常,因此您应该检查异常并记录它。尝试调试C API中的空返回值而不查看设置异常,就像尝试调试Python代码而不查看回溯一样。在无论如何,有几个明显的原因导致这个函数失败:也许你用一个越界索引调用它,或者你调用它的对象根本不是
list
。在事实上,第二个问题在这里似乎很明显。如果打印出
obj
会给您提供以下信息:<ConfigurationParser.LP_LED object at 0x7f678a06fcb0>
然后你得到了一个指向}s
LED
对象的(指针),而LED
对象不是{如果你看看你的代码,你似乎没有
list
对象,至少在你展示给我们的代码中没有。你确实有一个POINTER(LED)
,它可以保存一个由LED
组成的C数组,但这与其中的Pythonlist
不是一回事。它只是一个C数组,您可以使用C数组语法来取消引用:相关问题 更多 >
编程相关推荐