当使用加载时,我在跨共享库时遇到了一些异常无法正常运行的问题(或者至少,正如我所希望的;我知道这存在问题)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
致电给入口点() at A按预期工作,与抛出Foo()抛出异常并且入口点()抓住它。通话时间为B但是未能捕获异常。添加更多诊断代码显示类型信息Foo类在两个扩展中有所不同。改变两者的顺序dlopen调用没有区别,第二个加载的扩展失败。
我知道我可以通过使用来解决这个问题RTLD_GLOBAL作为附加标志dlopen,但是使用 dlopen 的应用程序(Matlab)超出了我的控制范围。有什么我可以做的吗mylib or myext1, myext2解决这个问题?
我必须避免在运行时使用 LD 标志(因为我无法控制运行 Matlab 二进制文件的用户)。还有其他建议吗?