У меня возникают проблемы с неправильным функционированием исключений (или, по крайней мере, как я надеюсь, я знаю, что есть проблемы с этим) через общие библиотеки при загрузке с помощью dlopen. Здесь я приведу несколько упрощенных примеров кода. Фактическая ситуация - myapp = Matlab, myext1 = расширение mexglx matlab, mylib - это общая библиотека моего кода между двумя расширениями (myext1, myext2)
mylib.h
struct Foo { Foo(int a); m_a; }
void throwFoo();
mylib.cpp
#include "mylib.h"
Foo::Foo(int a): m_a(a) {}
void throwFoo() { throw Foo(123); }
myext1.cpp
#include "mylib.h"
#include <iostream>
extern "C" void entrypoint()
{
try { throwFoo(); }
catch (Foo &e) { std::cout << "Caught foo\n"; }
}
myext2.cpp Идентично myext1.cpp
myapp.cpp
#include <dlfcn.h>
int main()
{
void *fh1 = dlopen("./myext1.so",RTLD_LAZY);
void *fh2 = dlopen("./myext2.so",RTLD_LAZY);
void *f1 = dlsym(fh1,"entrypoint");
void *f2 = dlsym(fh2,"entrypoint");
((void (*)())func1)(); // call myext1 (A)
((void (*)())func2)(); // call myext2 (B)
}
Компиляция этого кода:
g++ mylib.cpp -fPIC -o libmylib.so -shared
g++ myext1.cpp -fPIC -o myext1.so -shared -L. -lmylib -Wl,-rpath=.
g++ myext2.cpp -fPIC -o myext2.so -shared -L. -lmylib -Wl,-rpath=.
g++ myapp.cpp -fPIC -o myapp -ldl
Вызов to entrypoint() в A работает, как и ожидалось, с throwFoo(), бросая исключение и entrypoint(), ловя его. Однако вызов B не позволяет устранить исключение. Добавление более диагностического кода показывает, что типinfo для класса Foo отличается в двух расширениях. Изменение порядка двух вызовов dlopen не имеет значения, второе загруженное расширение выходит из строя.
Я знаю, что могу исправить это, используя RTLD_GLOBAL в качестве дополнительного флага для dlopen, но приложение (Matlab), использующее dlopen, вне моего контроля. Есть ли что-нибудь, что я могу сделать с mylib или myext1, myext2, чтобы исправить эту проблему?
Мне нужно избегать использования флагов LD для среды выполнения (поскольку я не могу управлять пользователями, использующими двоичный файл Matlab). Любые другие предложения?