4

I need to construct the following data type in Python for passing to a C function:

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 C I have this function:

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. What am I doing wrong? Isn't mystruct held sequentially in memory like a real C struct? 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?

2 Answers 2

5

You pass a pointer to an element of a structure by reference, using the offset of the element:

external_c_function(byref(mystruct,MyStruct.data.offset))
Sign up to request clarification or add additional context in comments.

Comments

2

It seems that when you reference mystruct.data, a copy of the data is made. I say this because the python command type(mystruct.data), returns str, rather than a C type.

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. Therefore you need to somehow do C style pointer arithmetic in python - i.e. get the address of mystruct (possibly using ctypes.pointer), then figure out a way to increment this pointer by the appropriate number of bytes.

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. However, you could always wrap external_c_function in another C function which does the necessary pointer arithmetic.

edit

Mark's answer solves the problem neatly. My comment about why the error occurs is still correct.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.