Reputation: 1371
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
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