WineHQ
WineHQ

5.3. Writing the wrapper

Firstly we will look at the simple example. The main complication of this case is the slightly different argument lists. The f parameter does not have to be passed to the Linux function and the d parameter (theoretically) has to be converted between unsigned long * and unsigned short *. Doing this ensures that the high bits of the returned value are set correctly. Also unlike with the ODBC example we will link directly to the Linux Shared Library.

/*
 * File: MyWin.c
 *
 * Copyright (c) The copyright holder.
 *
 * Basic Wine wrapper for the Linux 3rd party library so that it can be
 * used by the application
 *
 * Currently this file makes no attempt to be a full wrapper for the 3rd
 * party library; it only exports enough for our own use.
 *
 * Note that this is a Unix file; please don't go converting it to DOS format
 * (e.g. converting line feeds to Carriage return/Line feed).
 *
 * This file should be built in a Wine environment as a Winelib library,
 * linked to the Linux 3rd party libraries (currently libxxxx.so and
 * libyyyy.so)
 */

#include <3rd party linux header>
#include <windef.h> /* Part of the Wine header files */

/* This declaration is as defined in the spec file.  It is deliberately not
 * specified in terms of 3rd party types since we are messing about here
 * between two operating systems (making it look like a Windows thing when
 * actually it is a Linux thing).  In this way the compiler will point out any
 * inconsistencies.
 * For example the fourth argument needs care
 */
signed short WINAPI MyProxyWinFunc (unsigned short a, void *b, void *c,
                unsigned long *d, void *e, int f, char g, unsigned char *h)
{
    unsigned short d1;
    signed short ret;

    d1 = (unsigned short) *d;
    ret = 3rd party linux function (a, b, c, &d1, e, g, h);
    *d = d1;

    return ret;
}

/* End of file */

For a more extensive case we can use the ODBC example. This is implemented as a header file (proxyodbc.h) and the actual C source file (proxyodbc.c). Although the file is quite long it is extremely simple in structure.

DllMain the function is used to initialize the DLL. On the process attach event the function dynamically links to the desired Linux ODBC library (since there are several available) and builds a list of function pointers. It unlinks on the process detach event.

Then each of the functions simply calls the appropriate Linux function through the function pointer that was set up during initialization.