我有一些麻烦,异常不能正常工作(或至少,因为我希望;我知道这是有问题)跨共享库加载时使用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的entrypoint()的调用按预期工作,throwFoo()抛出异常并且entrypoint()捕获它.但在B的呼叫却无法捕获异常.添加更多诊断代码显示,Foo类的typeinfo在两个扩展中不同.更改两个dlopen呼叫的顺序没有任何区别,第二个加载的扩展失败.
我知道我可以通过使用RTLD_GLOBAL作为dlopen的附加标志来解决这个问题,但是使用dlopen的应用程序(Matlab)无法控制.有什么我可以用mylib或myext1,myext2来解决这个问题吗?