mtypes API Specification¶
mtypes.mtype is a metaclass that allows you to associate extra
C-level information with your type objects like classes within
Python. Also, objects instantiated from those types also have C-level
data associated with them.
PyMType_Type¶
PyMTypeObject PyMType_Type;
PyMType_Type is the base class for everything. This will be used
as the main type to generate all other mtypes.
PyMTypeObject¶
typedef struct _mtypeobject
{
PyHeapTypeObject ht_obj;
// The functions used for marshaling this type in and out of Python.
boxfunction box;
unboxfunction unbox;
PyMTypeFunction *mt_funcs;
void *mt_data;
} PyMTypeObject;
PyMTypeObject is essentially a PyTypeObject that allows for extra
functionality, effectively:
- Storing extra data within the object within the
mt_datamember. - Marshalling to and from C with the
__cdict__protocol via theboxandunboxmethods.
PyMTypeFunction¶
typedef struct _mfunc
{
// Analogous to ht_name, ht_slots and ht_qualname in PyHeapTypeObject
char *mt_name;
mt_func mt_slot;
char *mt_qualname;
PyMTypeArgument *arguments;
PyMTypeObject *mt_rettype;
} PyMTypeFunction;
PyMTypeFunction Is a struct that simply contains the functions that are implemented into the mtype.
This will have all the methods that relate to that specific function, and will associate the functions with
its basic attributes.
mt_nameis the argument that stores the name of the mtype.mt_slotsis of the type mt_func, defined in_mtypes.h. It will store the function pointer (and point to the C-level function).mt_qualnameis used to get information about the functionPyMTypeArgumentis explained below. It contains arguments that define the type.mt_rettypeis the return type of the function.
PyMTypeArgument¶
typedef struct _margument
{
// These fields are used to function signatures for a given function.
char *name;
PyMTypeObject *type;
} PyMTypeArgument;
PyMTypeArgument simply contains the function signature, unique to each function.
- char *name is the name of the function itself.
This is a Non-NULL value, returning an empty sting.
PyMTypeObject *typeis a pointer to the type of the argument.
PyMObject¶
typedef struct _mobject
{
PyObject obj;
void *m_data;
} PyMObject;
PyMObject It acts as an intermediary between the Python level
object and the C level object. It contains:
PyObject, which is the Python-Level Objectvoid *m_datawhich stores the C-level data that is needed for this object to be represented.
We will use the box and unbox methods to interface between
the Pythonic and C level objects via the __cdict__ protocol.
box and unbox¶
These functions will be used as the layer of translation between C structs and Python objects.
typedef PyObject *(*boxfunction)(PyMTypeObject *type, void *data);
typedef int (*unboxfunction)(PyObject *obj, void *data);
boxfunction¶
The box function is defined as the layer that converts a C struct into a
Python object. The function will perform error checking and will return
an instance of a PyMType.
Input Arguments¶
PyMTypeObject *type: The type that the C struct should be marshalled into.void *data: A pointer to the data that needs to be marshalled and converted to a Python Object.
Output Argument¶
PyObject *out: A pointer to aPyObjectinitalized on the heap from the C struct.NULLindicates failure. If returningNULL, a Python exception must be set. The returned object must be a pointer to either aPyMTypeObjectorPyMObjectwhich has the Python type oftype.
unboxfunction¶
The unbox function is a C function that takes in the Python object
to be marshalled into a C struct.
Input Arguments¶
PyObject *obj: The object to be marshalled into C. Its type must be an instance ofPyMTypeObject.void *data: A pointer to the C struct to put the data into.
Output Argument¶
int return_code: Must be-1on failure and0on success. If returning-1, a Python exception must be set.
__cdict__ protocol¶
The __cdict__ protocol will be used as an intermediary between
Python level objects and C structs. This will allow a specific type
signature to be passed from the Python Object into the unbox
function, then passing to a ctypes method, and then calling the
box function eventually returning a PyMObject.
This dict provides the boxfunction and the unboxfunction with
the proper associated C type signature.
from typing import Tuple, Dict
from ctypes import CFUNCTYPE
from mtypes import mtype
class MarshalledClass(metaclass=mtype):
__cdict__:
Dict[str, # Lookup by name
Dict[
paramflags_type, # Lookup by signature
CFUNCTYPE, # Implementation
],
]