Let's say I want to write a module called countries that contains information about the countries of the world. I want to write it in C. It will expose a member called countries which is a list of objects of type Country. The Country type has two members: name and capital, both strings. So we could do something like this:
>>> from countries import countries >>> countries[0].name Afghanistan >>> countries[0].capital Kabul Following the various scraps of tutorials I was able to find online, I figured out how to create my custom Country type in C. It looks basically like this:
typedef struct { PyObject_HEAD char *name; char *capital; } Country; static struct PyMemberDef CountryMembers[] = { {"name", T_OBJECT_EX, offsetof(Country, name), 0, "name"}, {"capital", T_OBJECT_EX, offsetof(Country, capital), 0, "capital"}, {NULL} }; static PyTypeObject CountryType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "countries.Country", .tp_doc = "Country", .tp_basicsize = sizeof(Country), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_new = PyType_GenericNew, .tp_members = CountryMembers }; and then in the module init function, call Py_TypeReady and add the type to the module. However, what I cannot figure out how to do is create a new instance of this type, in C, add it to the module, and populate its fields. The closest I can get is this, again in the module init function:
PyObject *afghanistan = PyObject_CallObject((PyObject*) &CountryType, NULL); PyModule_AddObject(local_module, "afghanistan", (PyObject*) afghanistan); But I don't know how to fill in the members.
T_OBJECT_EXandchar *don't match. EitherT_OBJECT_EXshould beT_STRING, orchar *should bePyObject *, depending on how you actually want these objects to work.Countryfrom Python.