Bri*_*edy 10 c++ matlab exception shared-libraries dlopen
在使用dlopen加载时,我遇到了一些异常无法正常运行的问题(或者至少,正如我希望的那样;我知道这有问题).我在这里包含一些简化的示例代码.实际情况是myapp = Matlab,myext1 = mexglx matlab扩展,mylib是我的代码在两个扩展之间的共享库(myext1,myext2)
mylib.h
struct Foo { Foo(int a); m_a; }
void throwFoo();
Run Code Online (Sandbox Code Playgroud)
mylib.cpp
#include "mylib.h"
Foo::Foo(int a): m_a(a) {}
void throwFoo() { throw Foo(123); }
Run Code Online (Sandbox Code Playgroud)
myext1.cpp
#include "mylib.h"
#include <iostream>
extern "C" void entrypoint()
{
try { throwFoo(); }
catch (Foo &e) { std::cout << "Caught foo\n"; }
}
Run Code Online (Sandbox Code Playgroud)
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)
}
Run Code Online (Sandbox Code Playgroud)
编译此代码:
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
Run Code Online (Sandbox Code Playgroud)
要调用入口点()在一个正常工作,与throwFoo()抛出异常和入口点()捕获它.然而,B的呼叫未能发现异常.添加更多诊断代码表明Foo类的typeinfo 在两个扩展中有所不同.更改两个dlopen调用的顺序没有区别,第二个加载的扩展失败.
我知道我可以通过使用RTLD_GLOBAL作为dlopen的附加标志来解决这个问题,但使用dlopen的应用程序(Matlab)是我无法控制的.有什么我可以用mylib或myext1,myext2来解决这个问题吗?
我必须避免在运行时使用LD标志(因为我无法控制运行Matlab二进制文件的用户).还有其他建议吗?
Alexandrescu & Sutter 的《C++ 编码标准》中的规则 62:
\n\n“62.Don\xe2\x80\x99t 不允许异常跨模块边界传播。”
\n\n虽然当你小心翼翼地做时它可以工作,但对于真正的可移植和可重用的代码来说,这是不可能的。我想说,在对共享库或 DLL 进行编程时,这是一个非常常见的一般规则,即不要跨模块边界传播异常。只需使用 C 风格的接口,返回错误代码,并在块内的导出函数内执行所有操作try { } catch(...) { };。另外,RTTI 不在模块之间共享,因此不要期望 Foo 在不同模块中具有相同的类型信息。
| 归档时间: |
|
| 查看次数: |
4570 次 |
| 最近记录: |