Using the C API when EmbeddingΒΆ
The C API is intended to be called from handwritten code in SIP generated modules. However it is also often necessary to call it from C or C++ applications that embed the Python interpreter and need to pass C or C++ instances between the application and the interpreter.
The API is exported by the SIP module as a sipAPIDef
data structure
containing a set of function pointers. The data structure is defined in the
SIP header file sip.h
. When using Python v2.7, or Python v3.1 or later the
data structure is wrapped as a Python PyCapsule
object. When using other
versions of Python the data structure is wrapped as a Python PyCObject
object. It is referenced by the name _C_API
in the SIP module dictionary.
Each member of the data structure is a pointer to one of the functions of the
SIP API. The name of the member can be derived from the function name by
replacing the sip
prefix with api
and converting each word in the
name to lower case and preceding it with an underscore. For example:
sipExportSymbol
becomesapi_export_symbol
sipWrapperCheck
becomesapi_wrapper_check
Note that the type objects that SIP generates for a wrapped module (see
Generated Type Structures, Generated Named Enum Type Objects and
Generated Exception Objects) cannot be refered to directly and must be
obtained using the sipFindType()
function. Of course, the
corresponding modules must already have been imported into the interpreter.
The following code fragment shows how to get a pointer to the sipAPIDef
data structure:
#include <sip.h>
const sipAPIDef *get_sip_api()
{
#if defined(SIP_USE_PYCAPSULE)
return (const sipAPIDef *)PyCapsule_Import("sip._C_API", 0);
#else
PyObject *sip_module;
PyObject *sip_module_dict;
PyObject *c_api;
/* Import the SIP module. */
sip_module = PyImport_ImportModule("sip");
if (sip_module == NULL)
return NULL;
/* Get the module's dictionary. */
sip_module_dict = PyModule_GetDict(sip_module);
/* Get the "_C_API" attribute. */
c_api = PyDict_GetItemString(sip_module_dict, "_C_API");
if (c_api == NULL)
return NULL;
/* Sanity check that it is the right type. */
if (!PyCObject_Check(c_api))
return NULL;
/* Get the actual pointer from the object. */
return (const sipAPIDef *)PyCObject_AsVoidPtr(c_api);
#endif
}
The use of SIP_USE_PYCAPSULE
means that code will run under all
versions of Python.