4

我需要在 Python 中构造以下数据类型以传递给 C 函数:

struct {
  unsigned a,b,c;
  char data[8];
};

但是,我实际上需要将指向数据字段的指针传递给函数,而不是指向结构的指针,而且我不知道该怎么做。

这是我到目前为止所拥有的:

from ctypes import *                                                           
class MyStruct(Structure):                                              
  _fields_ = [("a",c_uint), ("b",c_uint), ("c",c_uint), ("data",c_char*8)]
mystruct = MyStruct(0,1,8,"ABCDEFGH")
external_c_function(mystruct.data)

现在在 CI 中有这个功能:

int external_c_function(char *data) {
  int a = ((unsigned *)data)[-1];
  int b = ((unsigned *)data)[-2];
  int c = ((unsigned *)data)[-3];
  ...
}

问题是,当函数被调用时,“数据”正确指向“ABCDEFGH”,但是当我尝试获取它之前的其余结构数据时,它是垃圾。我究竟做错了什么?mystruct 不是像真正的 C 结构一样按顺序保存在内存中吗?我怀疑数组发生了一些有趣的事情:我真的在做这样愚蠢的事情吗?

struct {
  unsigned a,b,c;
  char *data; // -> char[8]
};

如果是这样,我该如何正确地做到这一点?

4

2 回答 2

5

您可以使用元素的偏移量通过引用传递指向结构元素的指针:

external_c_function(byref(mystruct,MyStruct.data.offset))
于 2012-11-15T04:36:28.090 回答
2

似乎当您引用 时mystruct.data,会制作数据的副本。我这样说是因为 python 命令type(mystruct.data)返回str,而不是 C 类型。

我认为您无法修改external_c_function以接受结构开头的指针,因为这将是最明显的解决方案。因此,您需要以某种方式在 python 中进行 C 风格的指针算术 - 即获取mystruct(可能使用ctypes.pointer)的地址,然后找出一种方法以适当的字节数增加该指针。

我不知道如何在 python 中进行这种指针运算,或者是否可以以任何稳健的方式进行。但是,您总是可以external_c_function使用另一个 C 函数来执行必要的指针运算。

编辑

马克的回答巧妙地解决了这个问题。我关于错误发生原因的评论仍然是正确的。

于 2012-11-15T04:23:59.010 回答