[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