У меня возникли проблемы с неправильным функционированием исключений (или, по крайней мере, как я надеюсь, я знаю, что есть проблемы с этим) в разделяемых библиотеках при загрузке с использованием 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
Вызов точка входа () в A работает как положено, с throwFoo () выбрасывает исключение и entrypoint () перехватывает его.Однако вызов на B не может перехватить исключение.Добавление дополнительного диагностического кода показывает, что typeinfo для класса Foo отличается в двух расширениях.Изменение порядка двух вызовов dlopen не имеет значения, второе загруженное расширение завершается неудачно.
Я знаю, что могу это исправить, используя RTLD_GLOBAL в качестве дополнительного флага для dlopen , но приложение (Matlab), использующее dlopen, находится вне моего контроля.Могу ли я что-нибудь сделать с mylib или myext1 , myext2 , чтобы решить эту проблему?
Я должен избегать использования флагов LD для времени выполнения (поскольку я не могу контролировать пользователей, использующих двоичный файл Matlab).Любые другие предложения?