arthropode
arthropode

Reputation: 1371

Interfacing a cpython extension with a C struct

I am trying to create a python extension to interface python with my C software. Mainly I need to made a big struct from C software accessible and modifiable in python, so I would like to create a Python class to do the intermediate, eg so that doing in python my_class.var_int = 1 would be reflected on the subjacent struct.

So I made a simple Python object, with the following subjactent data

typedef struct {
    PyObject_HEAD
    struct my_struct *struct_data; 
} CustomObject;

The problem is that with this method I need to define a getter and setter function for each field in my struct, which is huge (~300) even if there are mainly primitive fields such as int or double. And writing that many function will be error-prone and not very evolutive.

There is the simple method to define class member stored directly from in the Object struct :

static PyMemberDef Custom_members[] = {
    {"var_int1", T_INT, offsetof(CustomObject, var_int1), 0,
     "first name"},
    {"var_int2", T_int, offsetof(CustomObject, var_int2), 0,
     "last name"},
    {"var_double", T_DOUBLE, offsetof(CustomObject, var_doube), 0,
     "custom number"},
    {NULL}  
};

But in my case it won't work since the variables are not stored directly in the Object struct, but in a struct referenced by the Object.

Is there any simpler way to interface a struct with Python. Or am I stuck to define a getter and setter function for each of my struct field ?

Upvotes: 1

Views: 296

Answers (1)

ead
ead

Reputation: 34367

In order to be able to use PyMemberDef you need to change the memory layout of your class (struct_data is no longer pointer):

typedef struct {
    PyObject_HEAD
    struct my_struct struct_data; 
} CustomObject;

and now offsetof can be used again:

static PyMemberDef Custom_members[] = {
    {"var_int1", T_INT, offsetof(CustomObject, struct_data.var_int1), 0,
     "first name"},
     ...
    {NULL}  
};

As the offset in the PyMemberDef-definition should be the same for all instances of class CustomObject, it cannot depend on the address stored in the pointer struct_data.

So if there is no really good reason, why struct_data must be a pointer, the above solution has multiple advantages (less code, no memory management needed and so on).

Upvotes: 1

Related Questions