Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using boost in MATLAB MEX library, different from MATLAB's version

We're creating a number of MATLAB MEX files that use our communications library. This communication library uses Boost a lot. Now, MATLAB also uses boost internally, which means that in a standard setup, we cannot use a boost version different from the one that comes with MATLAB or all hell ensues.

Problem is, the boost version that comes with our reference version of matlab (boost 1.40) is quite old and has a few bugs. We'd very much like to use a newer version.

The only solution I see is to create a custom version of boost that lives in a different namespace. The name mangling should then prevent naming conflicts. This solution is a bit tricky because boost also exports some "C" symbols and has a number of macro's that will all need to be changed.

Are there any recommended solutions that don't require the creation of custom boost versions?

like image 940
Ives Avatar asked Dec 18 '12 13:12

Ives


1 Answers

One solution is to change the way matlab opens your plugin, by writing a small loader mex file which itself has no dependency on boost, call it foo.mexglx

It's mexFunction call simply does this

void mexFunction (int nlhs, mxArray * plhs[], int nrhs, mxArray * prhs[])
{
  gMexEntry (nlhs, plhs, nrhs, prhs);
}

where the gMexEntry variable is a function pointer declared as

typedef void (*entryfunc_t)(int, mxArray**, int, const mxArray**);
entryfunc_t gMexEntry;

and populated by a static constructor when the module is loaded (all error checking ignored for brevity).

fh = dlopen ('bar.mexglx', RTLD_NOW | RTLD_DEEPBIND );
void * p = dlsym (fh, "mexFunction");
gMexEntry = reinterpret_cast<entryfunc_t> (p);

The chain of events is that when Matlab calls your function, the thin wrapper with no boost dependency will open your function with the boost dependency using the RTLD_DEEPBIND option of dlopen, which will place the lookup scope of the symbols in this library (using your version of boost) ahead of the global scope (using Matlab's old boost). Then the actual mexFunction call will forward to bar.

If you do your cmdline linking correctly, using 'ldd' you should see that 'foo.mexglx' has no dependency on boost, and 'bar.mexglx' has all your usual dependencies.

I've been using this technique heavily for months with no obvious signs of failure. I do still have some slight concerns that something I don't understand might go wrong, but for the time being this is the only solution I've got (other than writing a full out-of-process execution engine replicating the mxArray interface and communicating with pipes, or linking everything statically which isn't practical for my situation)

like image 125
Brian O'Kennedy Avatar answered Nov 01 '22 00:11

Brian O'Kennedy