我已尝试阅读有关此主题的所有问题/答案,但我无法正常工作。我要做的就是将结构发送到共享对象,然后将其返回并可以访问。
我已经设法创建了一个结构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];
答案 0 :(得分:1)
我已经创建了一个我自己的小例子。仔细看看 Python 代码后,我可以找出函数头(我还添加了一些虚拟体)。
问题很简单,函数返回一个CONNECTOR
指针,为了访问其成员,你需要" dereference"首先,否则你将获得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
并且可以& #39;被编入索引(不定义__getitem__
)。
关于第二种方法(直接调用函数),它也是同样的问题。这是一些有效的代码:
pconnector1 = testlib.square_array(ctypes.byref(con[0]))
connector1 = pconnector1.contents
print(type(connector1))
注意:我在 Win10 x64 上使用了 Python 2.7.10 ,但这里没有任何内容应该是 Python 版本或特定于平台。