I have had multiple occasions where I needed to quickly generate bindings to an existing C library. The repetitive nature of creating these bindings calls out for a tool to automate this tool. For this purpose, I have written a class, MG_DLM, that allows:

1. creating wrapper binding for routines from a header prototype declaration (with some limitations from standard C)
2. creating routines which access variables and pound defines
3. allow adding custom routines written by the developer

I have used MG_DLM to create bindings for the GNU Scientific Library (GSL), CULA, MAGMA, and even IDL itself.

#### Define the routines

For our example, let’s make some basic random number generation routines from GSL available. The relevant routines from the gsl_rng.h header file that we would like to access from IDL are:

const gsl_rng_type *gsl_rng_env_setup(void);
gsl_rng *gsl_rng_alloc(const gsl_rng_type *T);
INLINE_DECL double gsl_rng_uniform(const gsl_rng *r);


We need to write a modified header file that MG_DLM will be able to understand. Since the pointers to gsl_rng_type and gsl_rng are returned by one routine and passed into another, we can just define them as IDL_PTRINT. For example, GSL_RNG_ALLOC will just return a 64-bit integer that represents a pointer to a gsl_rng. This integer can then be passed to GSL_RNG_UNIFORM. Our header will be:

void gsl_rng_env_setup();
IDL_PTRINT gsl_rng_alloc(IDL_PTRINT t);
double gsl_rng_uniform(IDL_PTRINT r);


We place these definitions in mg_gsl_rng_bindings.h for use when we create the DLM object.

#### Create the DLM

Next, we use MG_DLM to define our DLM containing these bindings. First, create a DLM object with basic metadata:

dlm = mg_dlm(basename='mg_gsl', $prefix='MG_',$
name='mg_gsl', $description='IDL bindings for GSL',$
version='1.0', $source='Michael Galloy')  Next, tell the DLM where the include directory and library are: dlm->addInclude, 'gsl/gsl_rng.h',$
dlm->addLibrary, 'libgsl.a', $lib_directory='/usr/local/lib',$
/static



For our example, we will also need to access the gsl_rng_default variable in the GSL library. In gsl_rng.h, it is declared as:

GSL_VAR const gsl_rng_type *gsl_rng_default;


To add a routine that accesses this variable, we just do:

dlm->addVariableAccessor, 'gsl_rng_default', type=14L


Finally, tell the DLM to write itself, both the .c and .dlm files, and then build itself:

dlm->write
dlm->build


We are now ready to use our DLM.

#### Example of using

We can now use our routines to generate random numbers from IDL:

n = 1000L

mg_gsl_rng_env_setup
t = mg_gsl_rng_default()
r = mg_gsl_rng_alloc(t)

u = dblarr(n)
for i = 0L, n - 1L do u[i] = mg_gsl_rng_uniform(r)


Get the code for creating bindings (and a slightly more fleshed out set of GSL bindings) from the mglib repo.