typeinfo, bibliotecas compartilhadas e dlopen () sem RTLD_GLOBAL
Estou tendo problemas com exceções que não estão funcionando corretamente (ou pelo menos, como eu esperaria; eu sei que há problemas com isso) nas bibliotecas compartilhadas quando carregadas usandodlopen. Incluo aqui algum código de exemplo simplificado. A situação real émyapp= Matlab,myext1= extensão mexglx matlab,mylib é uma biblioteca compartilhada do meu código entre as duas extensões (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 Idêntico ao 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)
}
Compilando este código:
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 chamada paraponto de entrada() àsA funciona como esperado, comthrowFoo () lançando a exceção eponto de entrada() pegando. A chamada emB no entanto, falha em capturar a exceção. Adicionar mais código de diagnóstico mostra que o typeinfo para oFoo A classe difere nas duas extensões. Alterando a ordem dos doisdlopen chamadas não faz diferença, o segundo ramal carregado falha.
Eu sei que posso consertar isso usandoRTLD_GLOBAL como uma bandeira adicional paradlopen, mas o aplicativo (Matlab) usando dlopen está fora de meu controle. Existe algo que eu possa fazer commylib oumyext1, myext2 corrigir esse problema?
Eu tenho que evitar o uso de sinalizadores LD para o tempo de execução (já que não consigo controlar os usuários que executam o binário do Matlab). Alguma outra sugestão?