C API from an Extension Unit in Python | Set 1

Python Methods and Functions

Code # 1: [C code] Point objects including some helper functions

# Destructor function for points

static void del_Point (PyObject * obj )

{

free (PyCapsule_GetPointer (obj, " Point " ) ); 

}

 

static PyObject * PyPoint_FromPoint (Point * p, int must_free)

{

return PyCapsule_New (p, "Point" , must_free? del_Point: NULL); 

}

 
# Utility functions 

static Point * PyPoint_AsPoint (PyObject * obj)

{

return (Point *) PyCapsule_GetPointer (obj, " Point " ); 

}

Now the problem to deal with is how to handle the export of the functions PyPoint_AsPoint() and PyPoint_FromPoint () as an API that can be used and referenced to other plugins. ( For example, any other extensions also want to use wrapped Point objects.)

Code # 2: Introducing a new header file named Pythonsample.h for work extension.

// pythonsample.h
# include "Python.h"
# include "work.h"
# ifdef __cplusplus

 

extern "C" {

# endif

 
// Open API table

typ edef struct

{

Point * (* aspoint) (PyObject *); 

PyObject * (* frompoint) (Point *, int ); 

} _PointAPIMethods; 

 
# ifndef PYTHONSAMPLE_MODULE

 

/ * Method table in external module * /

static _ PointAPIMethods * _point_api = 0; 

Code # 3: Importing an API table from " work "

static int import_sample ( void )

{

_ point_api = (_PointAPIMethods *) PyCapsule_Import ( " work._point_api " , 0); 

return (_ point_api! = NULL)? 10; 

}
/ * Macros for implementing the programming interface * /
# define PyPoint_AsPoint (obj) (_point_api- & gt; aspoint) (obj)
# define PyPoint_FromPoint (obj) ( _point_api- & gt; frompoint) (obj)
# endif
# ifdef __cplusplus
}
# endif

The _PointAPIMethods function pointer table is the most important function, as it will be initialized in the exporter and found when the modules are imported. The code below shows how to modify the original plugin to populate the table and export it.

Code # 4: Destructor and Utility Function

/ / pythonsample.c

# include & quot; Python.h & quot;
# define PYTHONSAMPLE_MODULE
# include & quot; pythonsample.h & quot;

 

/ / Destructor function for points 

static void del_Point (PyObject * obj)

{

  printf ( " Deleting point " ); 

free (PyCapsule_GetPointer (obj, "Point" )); 

}

 

/ / Utility functions

static Point * PyPoint_AsPoint (PyObject * obj)

{

return (Point * ) PyCapsule_GetPointer (obj, "Point" ); 

}

 

static PyObject * PyPoint_FromPoint (Point * p, int free)

{

return PyCapsule_New (p, "Point" , free? del_Point: NULL); 

}

 

static _PointAPIMethods _point_api =

{

PyPoint_AsPoint,

PyPoint_FromPoint

}; 

Code # 5: module function

// Module initialization function

 
PyMODINIT_FUNC

PyInit_sample ( void )

{

PyObject * m; 

PyObject * py_point_api; 

m = PyModule_Create (& amp; samplemodule); 

if (m == NULL)

return NULL; 

 

// Add Point C API Functions

  py_point_api = PyCapsule_New (( void *) & amp; _point_api, "work._point_api" , NULL); 

if (py_point_api)

{

PyModule_AddObject (m, " _ point_api " , py_point_api); 

}

return m; 

}





Get Solution for free from DataCamp guru