2012-12-18 10 views
11

Tworzymy wiele plików MATLAB MEX, które korzystają z naszej biblioteki komunikacyjnej. Ta biblioteka komunikacyjna znacznie zwiększa Boost. Teraz MATLAB korzysta również z wewnętrznego wzmocnienia, co oznacza, że ​​w standardowej konfiguracji nie możemy użyć wersji boost innej niż ta, która pochodzi z MATLAB lub z całego piekła.Używanie boost w bibliotece MATLAB MEX, innej niż w wersji MATLAB

Problem polega na tym, że wersja doładowania dostarczana z naszą referencyjną wersją programu Matlab (doładowanie 1.40) jest dość stara i zawiera kilka błędów. Bardzo chcielibyśmy użyć nowszej wersji.

Jedyne rozwiązanie, jakie widzę, to stworzenie niestandardowej wersji boost, która żyje w innym obszarze nazw. Wymazywanie nazw powinno następnie zapobiegać konfliktom nazw. To rozwiązanie jest nieco skomplikowane, ponieważ funkcja boost również eksportuje niektóre symbole "C" i zawiera wiele makr, które będą musiały zostać zmienione.

Czy są jakieś zalecane rozwiązania, które nie wymagają tworzenia niestandardowych wersji doładowania?

+0

Czy próbowałeś podać pełną ścieżkę twojej biblioteki Boost za pomocą opcji '-l'? –

+0

Dlaczego to ma znaczenie? I tak spróbuję jutro, po prostu ciekawi. – Ives

+0

może w ten sposób może łączyć się z twoją biblioteką Boost, a nie z MATLAB-em. –

Odpowiedz

9

Jednym z rozwiązań jest zmiana sposobu Matlab otwiera swoje wtyczki, pisząc plik mex mała ładowarka, która sama nie ma uzależnienia od podbicia, nazwać foo.mexglx

To wezwanie mexFunction po prostu robi to

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

gdzie zmienna gMexEntry jest wskaźnikiem funkcja zadeklarowana jako

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

i wypełnione przez konstruktor statyczny, gdy moduł jest załadowany (wszystkie sprawdzenia błędów są ignorowane dla zwięzłości).

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

Łańcuch zdarzeń jest to, że gdy Matlab nazywa swoją funkcję, cienka owijka bez uzależnienia doładowania otworzy swoją funkcję z uzależnienia doładowania przy użyciu opcję RTLD_DEEPBIND z dlopen, który umieści zakresu odnośnika symboli w tej bibliotece (używając twojej wersji boost) przed globalnym zasięgiem (używając starego boostu Matlaba). Następnie faktyczne wywołanie funkcji mexFunction będzie przekazywane do paska.

Jeśli wykonać CmdLine łącząc prawidłowo, stosując „ldd” powinieneś zobaczyć, że „foo.mexglx” ma zależność impuls i „bar.mexglx” ma swoje zwyczajowe wszystkie zależności.

Używam tej techniki ciężko przez wiele miesięcy bez oczywistych oznak niepowodzenia. Nadal mam pewne obawy, że coś, czego nie rozumiem, może pójść nie tak, ale na razie jest to jedyne rozwiązanie, jakie mam (poza napisaniem pełnego silnika wykonawczego poza procesem, replikującego interfejs mxArray i komunikując się z rurami lub łącząc wszystko statycznie, co nie jest praktyczne w mojej sytuacji)

+2

Zakładając, że instalujesz inne biblioteki mex, aby załadować je w tej samej lokalizacji, co _foo.mexglx_, sugeruję dodanie opcji -Wl, -rpath-Wl, $ ORIGIN' do flag łącznika podczas budowania _foo.mexglx_, aby nie było trzeba zabezpieczyć się 'LD_LIBRARY_PATH', itp. podczas próby załadowania bibliotek przez' dlopen'. – eric