Ctypes:将返回的指针映射到结构

我已经尝试阅读关于这个主题的所有问题/答案,但我无法得到任何工作。 我要做的就是将结构发送到共享对象,然后将其返回并可访问。

我已经设法创建一个结构OK,我可以将它传递给共享对象。 我知道这一点,因为如果从结构中返回一个特定的值,它可以正常工作。 Python中的结构定义如下所示:

class ROW(ctypes.Structure): _fields_ = [("Address",ctypes.c_int16), ("FirstRegister",ctypes.c_int16), ("NumberOfRegisters",ctypes.c_int16), ("Sampling", ctypes.c_int16)] class CONNECTOR(ctypes.Structure): _fields_ = [("NumberOfRows", ctypes.c_int16), ("Rows", ROW * 200)] # Initialise an array of connectors (CON1, CON2, CON11, CON12) ConArray = CONNECTOR * 4 con = ConArray() # Initialise an array of ROW struct RowArray = ROW * 200 row = RowArray() 

然后,我使用来自SQLite数据库的数据填充结构,并可以使用con[n].Rows[m].Address等访问特定数据。

我目前正在尝试一次发送一个连接器,并返回完全相同的结构。

相关代码如下:

 testlib = ctypes.cdll.LoadLibrary('_example.so') x = testlib.square_array x.argtype = ctypes.POINTER(CONNECTOR) x.restype = ctypes.POINTER(CONNECTOR) y = x(ctypes.byref(con[0])) 

我尝试过很多不同的调用函数的方法,但这个方法似乎是最有希望的。 问题是当我尝试然后使用y.Rows[0].Address[0]访问特定值时,会发生错误: AttributeError: 'LP_CONNECTOR' object has no attribute 'Rows'

相反,我只是直接调用函数:

 x = testlib.square_array(ctypes.byref(con[0])) 

我收到一个int ,我假设它代表一个内存地址,例如: 35664848

我尝试过各种各样的选择,但我对C很不熟悉(一位同事将处理代码的所有C方面)。 有没有提出的解决方案? 我觉得我只是错过了一件小事,但为了达到这一点,我花了很多天。

更新:添加了C代码

C代码如下所示:

example.c:

  #include "example.h" CONNECTOR* square_array(CONNECTOR* con) { printf("Value of Row 0 Address%i\n",con->Rows[0].Address); return (con); } 

example.h文件:

 struct ROW; struct CONNECTOR; typedef struct { short int Address; short int FirstRegister; short int NumberOfRegisters; short int Sampling; }ROW; typedef struct { short int NumberOfRows; ROW Rows[200]; }CONNECTOR; CONNECTOR Connectors[4]; 

我已经创建了一个我自己的小例子。 仔细看看Python代码后,我可以找出函数头(我还添加了一些虚拟体)。

问题很简单,函数返回一个CONNECTOR指针,为了访问它的成员,你需要首先“取消引用”它,否则你将获得AttributeError 。 这是你的代码(稍加修改):

 testlib = ctypes.cdll.LoadLibrary("_example.so") testfunc = testlib.square_array testfunc.argtype = ctypes.POINTER(CONNECTOR) testfunc.restype = ctypes.POINTER(CONNECTOR) pconnector0 = testfunc(ctypes.byref(con[0])) connector0 = pconnector0.contents print(connector0.NumberOfRows) print(connector0.Rows[0].Address) 

“秘密”在于pconnector0.contents ,它执行“解除引用”。

作为旁注,代码行y.Rows[0].Address[0]将触发TypeError因为末尾有[0]Address是一个int而且不能被索引(不定义__getitem__ ) 。

关于第二种方法(直接调用函数),这是同样的问题。 这是一些有效的代码:

 pconnector1 = testlib.square_array(ctypes.byref(con[0])) connector1 = pconnector1.contents print(type(connector1)) 

注意 :我在Win10 x64上使用了Python 2.7.10 ,但这里没有任何内容应该是Python版本或特定于平台的。