Wrapping C Functions

Now we have all the enumerations and structures declared we now have to wrap the C functions. In general, to convert a C function declaration to Pyrex you:

  1. Remove const keywords,
  2. Remove ; from the end of the line, and
  3. Replace (void) with ().

XOSD

Consider the following C function declaration.

xosd *xosd_create (int number_lines);

It declares a function, xosd_create, which takes one argument (number_lines). The Pyrex declaration of the same function looks very similar.

    xosd *xosd_create(int number_lines)
xosd *
is what is returned by the function.
xosd_create
is the name of the function. This has to be the same as the name in the .h file.
(int number_lines)
is the argument.

Note that the function declaration is indented because it belongs in the same cdef extern from block as the enumerations.

Variable-Length Arguments

C, like Python, can handle variable length arguments. The conversion between C var-args and Pyrex var-args is fairly strait forward. Consider the function declaration:

int xosd_display (xosd *osd, int line, 
                  xosd_command command, ...);

After the three compulsory arguments (osd, line and command), the function xosd_display can take a variable number of arguments. To emulate this in Pyrex we also write ellipsis:

    int xosd_display(xosd *osd, int line,
                     xosd_command command, 
                     ...)

Be warned, things get more complicated later on.

CUPS

Call by Reference

Call by reference is done in a similar way to call by value. Consider the following.

extern int cupsGetDests(cups_dest_t **dests);

Here dests will be modified when cupsGetDests returns. In Pyrex, the call would look like the following.

    int cupsGetDests(cups_dest_t **dests)

We have to have declared the type of the argument, cups_dest_t, before we declared the function.

Using Incomplete Types

The declaration of cupsPrintFile requires a pointer to a cups_option_t.

extern int cupsPrintFile(const char *printer,
                         const char *filename,
                         const char *title, int num_options,
                         cups_option_t *options);

In our simple example we are not going to pass any options to the printer, so we declare cups_option_t as an incomplete type before declaring cupsPrintFile.

    ctypedef cups_option_t
    int cupsPrintFile(char *printer, char *filename,
                      char *title, int num_options,
                      cups_option_t *options)