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

标签 python c ctypes

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

我已经成功地创建了一个结构,我可以将它很好地传递给共享对象。我知道这一点,因为如果从结构中返回特定值,它工作正常。 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代码如下:

例子.c:

 #include "example.h"

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

例子.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.argtypes = (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)

“ secret ”在于执行“解引用”的pconnector0.contents

作为旁注,由于 [ 0] 最后:Address 是一个 int 并且不能被索引(没有定义 __getitem__).

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

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

注意事项:

关于python - Ctypes:将返回的指针映射到结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43000568/

相关文章:

python - Django - 如何在不修改的情况下扩展 3rd 方模型

The C Programming Language 1.9 中示例的冲突类型

c++ - 无法使用g++用C++代码编译C库

python - 使用 SWIG 使用 3rd-Party 驱动程序构建 Python 模块

Python 模块导入 : Single-line vs Multi-line

javascript - get() 无法找到 POST 数据

python - 编辑 Ctypes 结构的缓冲区

python - 使用 ctypes 时释放内存

javascript - Python 中的 Web 套接字(使用 flask )问题

c - 在 Delphi 程序中使用 CUDA 调用运行 C 函数