简体   繁体   English

ctypes将指针传递给结构中的字段

[英]ctypes passing a pointer to a field in a struct

I need to construct the following data type in Python for passing to a C function: 我需要在Python中构造以下数据类型以传递给C函数:

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

However, I need to actually pass a pointer to the data field to the function, not a pointer to a struct, and I can't figure out how to do this. 但是,我需要实际将指向数据字段的指针传递给函数,而不是指向结构的指针,我无法弄清楚如何执行此操作。

Here is what I have so far: 这是我到目前为止:

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)

Now in CI have this function: 现在在CI中有这个功能:

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

The problem is, when the function gets called, "data" correctly points to "ABCDEFGH", but when I try to get the rest of the struct data preceding it, it is garbage. 问题是,当函数被调用时,“data”正确地指向“ABCDEFGH”,但是当我尝试获取其前面的其余struct数据时,它就是垃圾。 What am I doing wrong? 我究竟做错了什么? Isn't mystruct held sequentially in memory like a real C struct? mystruct不是像真正的C结构那样在内存中按顺序存在吗? I suspect something funny is going on with the array: am I actually doing something silly like this? 我怀疑阵列发生了一些有趣的事情:我实际上是在做这样傻事吗?

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

and if so, how do I do it correctly? 如果是这样,我该怎么做呢?

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

external_c_function(byref(mystruct,MyStruct.data.offset))

It seems that when you reference mystruct.data , a copy of the data is made. 看来,当您引用mystruct.data ,会生成一份数据副本。 I say this because the python command type(mystruct.data) , returns str , rather than a C type. 我这样说是因为python命令type(mystruct.data)返回str而不是C类型。

I presume that you are not able to modify the external_c_function to accept the pointer at the start of the structure, as this would be the most obvious solution. 我假设您无法修改external_c_function以接受结构开头的指针,因为这将是最明显的解决方案。 Therefore you need to somehow do C style pointer arithmetic in python - ie get the address of mystruct (possibly using ctypes.pointer ), then figure out a way to increment this pointer by the appropriate number of bytes. 因此,您需要以某种方式在python中执行C样式指针算法 - 即获取mystruct的地址(可能使用ctypes.pointer ),然后找出一种方法来将此指针递增适当的字节数。

I don't know how you can do such pointer arithmetic in python, or if it's even possible to do in any robust manner. 我不知道你如何在python中做这样的指针算法,或者甚至可以以任何健壮的方式做。 However, you could always wrap external_c_function in another C function which does the necessary pointer arithmetic. 但是,您始终可以将external_c_function包装在另一个执行必要指针算术的C函数中。

edit 编辑

Mark's answer solves the problem neatly. 马克的答案整齐地解决了这个问题。 My comment about why the error occurs is still correct. 我对错误发生原因的评论仍然是正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM