c++ - typeinfo, shared libraries and dlopen() without RTLD_GLOBAL -


i'm having trouble exceptions not functioning correctly (or @ least, hope; know there issues this) across shared libraries when loaded using dlopen. include simplified example code here. actual situation myapp=matlab, myext1=mexglx matlab extension, mylib shared library of code between 2 extensions (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 identical 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) } 

compiling code:

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 

the call entrypoint() @ a works expected, throwfoo() throwing exception , entrypoint() catching it. call @ b fails catch exception. adding more diagnostic code shows typeinfo foo class differs in 2 extensions. changing order of 2 dlopen calls makes no difference, second loaded extension fails.

i know can fix using rtld_global additional flag dlopen, application (matlab) using dlopen out of control. there can mylib or myext1, myext2 fix problem?

i have avoid using ld flags runtime (since cannot control users running matlab binary). other suggestions?

rule 62 in "c++ coding standards" alexandrescu & sutter:

"62. don’t allow exceptions propagate across module boundaries."

although can work when carefully, true portable , reusable code, cannot done. pretty common general rule when programming shared libraries or dlls, not propagate exceptions across module boundaries. use c-style interface, return error codes, , inside exported function inside try { } catch(...) { }; block. also, rtti not shared across modules, don't expect foo have same typeinfo in different modules.


Comments

Popular posts from this blog

apache - Add omitted ? to URLs -

redirect - bbPress Forum - rewrite to wwww.mysite prohibits login -

php - How can I stop spam on my custom forum/blog? -