[Pyrex] Public C API support for Pyrex

Stefan Behnel behnel_ml at gkec.informatik.tu-darmstadt.de
Tue Jul 4 10:16:50 UTC 2006


Hi all,

following a recent thread on public C functions in Pyrex, I wrote a patch that
allows writing public C APIs for Pyrex modules, simply by making C functions
"public" (which did not have a well defined meaning or even any visible effect
before).

It works mainly as encouraged by
http://docs.python.org/dev/ext/using-cobjects.html

The result is a new "_import_c_api" attribute in the Pyrex generated module
that exists only if public functions were declared for that module. The
attribute contains a PyCObject that points to a module internal C function.
When calling it from external extension modules, you pass a pointer to a
struct of this type:

{
{ "function_name", &myfunctionpointer },
...,
{0, 0}
}

The function updates the pointers that are referenced in the struct to point
to the named API functions. On error (i.e. if a name is not known), it sets an
exception and returns -1.

This means you can define your 'imported' API function like this:

static elementtype*((*_elementFactory)(doctype*,int));
static struct {char *s; void **p;} _etree_API[] = {
  {"_elementFactory", &_elementFactory},
  {0, 0}
};

then call the setup function on "_etree_API" and use your _elementFactory
function just as any other function defined in your program.

Pyrex also writes support code for this procedure into the generated header
file. In the likely case that you #include it, it will provide you with all
declared API functions under their normal name *AFTER* you have called the
static function

    import_MODULENAME(imported_module)

with the Python imported module object as argument. This function is easily
declared in a Pyrex .pxd as

     cdef int import_MODULENAME(module) except -1


The idea for "good practice usage" is to provide a .pxd file for the public
API that defines all public functions as well as the above import function
based on the generated .h file. Something like:

cdef extern from "etree.h":
     cdef int import_etree(etree_module) except -1      # import function
     cdef class lxml.etree._Document [ object LxmlDocument ]: # public class
         cdef int some_content
     cdef _elementFactory(_Document doc, int node_id)         # public C func

This specifies the public API and allows direct importing in external Pyrex
modules.

Hoping for inclusion (in 0.9.5 or whatever the next release will be),

Stefan
-------------- next part --------------
A non-text attachment was scrubbed...
Name: public-api.patch
Type: text/x-patch
Size: 7984 bytes
Desc: not available
Url : http://lists.copyleft.no/pipermail/pyrex/attachments/20060704/44dbedff/attachment.bin 


More information about the Pyrex mailing list