typeinfo, общие библиотеки и dlopen () без RTLD_GLOBAL

У меня проблемы с некорректной работой исключений (или, по крайней мере, как я надеюсь; я знаю, что с этим есть проблемы) в разделяемых библиотеках при загрузке с использованием 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

Вызов entrypoint () at A работает должным образом, при этом throwFoo () генерирует исключение, а entrypoint () перехватывает его. Однако вызов на B не может перехватить исключение. Добавление дополнительного диагностического кода показывает, что информация о типе для класса Foo отличается в двух расширениях. Изменение порядка двух вызовов dlopen не имеет значения, второе загруженное расширение не работает.

Я знаю, что могу исправить это, используя RTLD_GLOBAL в качестве дополнительного флага для dlopen , но приложение (Matlab), использующее dlopen, находится вне моего контроля. Могу ли я что-нибудь сделать с mylib или myext1 , myext2 , чтобы решить эту проблему?

Я должен избегать использования LD-флагов во время выполнения (поскольку я не могу контролировать пользователей, запускающих двоичный файл Matlab). Есть ли другие предложения?

10
задан Brian O'Kennedy 18 February 2011 в 18:15
поделиться