C to Eiffel--Using SWIG to export the regression functions

Luckily, this process is as easy as it was back when we were originally exporting the Python/C API to Eiffel, and just as quick. By cutting and pasting lines from the ihc-generated header file Regression.h, we get the following as our module definition for SWIG:

Example 13-7. The Regression.i SWIG interface file

%module regression
%{
#include "Regression.h"
%}

double  beta_0 ( /*[in, size_is(len_xs)]*/double* xs
               , /*[in]*/int len_xs
               , /*[in, size_is(len_ys)]*/double* ys
               , /*[in]*/int len_ys );
/*[pure]*/
double  beta_1 ( /*[in, size_is(len_xs)]*/double* xs
               , /*[in]*/int len_xs
               , /*[in, size_is(len_ys)]*/double* ys
               , /*[in]*/int len_ys );

extern void startupHaskell( int argc, char argv[][] );
extern void start_haskell( void );

The above needs a touch of explanation. The beta_0 and beta_1 functions are those we wanted to export, but, just as we had to initialize the Python interpreter, we must also initialize the Haskell runtime. Unfortunately, the actual function to do this is startupHaskell, which takes a pointer to an array of strings--but SWIG persists in translating this into just a single string for Eiffel, and the result is a mess. We were never able to call startupHaskell directly, but instead wrote a simple wrapper function in C with no arguments, which was easily usable from Haskell:

Example 13-8. The wrap_start_haskell.c file, with obviously fake "arguments"

extern void startupHaskell( int argc, char**argv );

void start_haskell( void )
{
	char * argv[] = { "bob", "tim" };
	startupHaskell( 1, argv );
}

True to form, SWIG generated the REGRESSION_WRAPPER class, and we were on our way.