2012-12-18 12 views
11

Stiamo creando un numero di file MATLAB MEX che utilizzano la nostra libreria di comunicazioni. Questa libreria di comunicazione utilizza molto il Boost. Ora, MATLAB usa anche boost internamente, il che significa che in una configurazione standard, non possiamo usare una versione di boost diversa da quella fornita con MATLAB o che ne consegue.Uso della spinta nella libreria MATLAB MEX, diversa dalla versione di MATLAB

Il problema è che la versione potenziata fornita con la nostra versione di riferimento di matlab (boost 1.40) è piuttosto vecchia e presenta alcuni bug. Ci piacerebbe molto usare una versione più recente.

L'unica soluzione che vedo è creare una versione personalizzata di boost che risiede in un namespace diverso. Il nome mangling dovrebbe quindi prevenire i conflitti di denominazione. Questa soluzione è un po 'complicata perché boost esporta anche alcuni simboli "C" e ha un numero di macro che dovranno essere tutte modificate.

Esistono soluzioni consigliate che non richiedono la creazione di versioni boost personalizzate?

+0

Hai provato a specificare il percorso completo della tua libreria Boost con l'opzione '-l'? –

+0

Perché dovrebbe importare? Ci proverò comunque domani, solo curioso. – Ives

+0

forse in questo modo può collegarsi con la libreria Boost piuttosto che con MATLAB. –

risposta

9

Una soluzione è quella di cambiare il modo in cui MATLAB apre il plugin, scrivendo un file mex piccolo caricatore che di per sé non ha dipendenze da spinta, lo chiamano foo.mexglx

E 'chiamata mexFunction fa semplicemente questo

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

dove la variabile gMexEntry è un puntatore alla funzione dichiarata come

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

e popolato da un costruttore statico quando il modulo viene caricato (tutti gli errori controllati vengono ignorati per brevità).

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

La catena di eventi è che quando Matlab chiama la funzione, l'involucro sottile con alcuna dipendenza spinta si aprirà la funzione con la dipendenza spinta utilizzando l' possibilità RTLD_DEEPBIND di dlopen, che porrà l'ambito di ricerca dei simboli in questa libreria (utilizzando la tua versione di boost) in vista dell'ambito globale (utilizzando il vecchio boost di Matlab). Quindi la chiamata mexFunction effettiva verrà inoltrata a bar.

Se fate la vostra cmdline che collega in modo corretto, utilizzando 'ldd' si dovrebbe vedere che 'foo.mexglx' non ha dipendenze da spinta, e 'bar.mexglx' ha tutti i soliti dipendenze.

Ho usato questa tecnica pesantemente per mesi senza evidenti segni di insuccesso. Ho ancora qualche lieve preoccupazione che qualcosa che non capisco possa andare storto, ma per il momento questa è l'unica soluzione che ho (oltre a scrivere un motore di esecuzione out-of-process completo che replica l'interfaccia mxArray e comunicare con pipe, o collegare staticamente tutto ciò che non è pratico per la mia situazione)

+2

Supponendo che si stiano installando le altre librerie mex da caricare nella stessa posizione di _foo.mexglx_, suggerisco di aggiungere '-Wl, -rpath -Wl, $ ORIGIN' ai flag del linker quando si costruisce _foo.mexglx_ in modo da non è necessario eseguire il muck con 'LD_LIBRARY_PATH', ecc. quando si tenta di caricare le librerie tramite' dlopen'. – eric

Problemi correlati