Hello. I'm working with boost::any and shared_ptr. I'm implementing a plugin system which uses registration from .so files (under Linux). The problem is that I have a factory function which returns boost::any. This boost::any object holds a pointer type. The problem is that when I try to get the registered type back to its real type through boost::any_cast, the cast always fails. If I register this type in the same executable as the application, everything is ok, and I can cast back to its real type.I have no idea why this happens: template <class T> struct ObjectFactory { boost::any operator()() const { typedef typename T::interface_type it; it * t = new T(); return t; } }; #define REGISTER_EXTENSION_NODE(extensionpoint, ns) \ namespace { \ static const bool registeredextensionnode = \ ::Gtk::Util::PluginsManager::instance().register_extension_node(#ns "::" #extensionpoint, \ ::Gtk::Util::detail::ExtensionNodeFactoryns::extensionpoint()); \ } These are the implied parts of my application. If I use the macro from a .so, it fails. If I use it from the .exe, everything's ok. The registration part seems to work, I checked the size of the containers and so on, and the elements were inserted. Any help how could I solve this? I've been trying to debug the problem for almost 4 hours with no luck.
AMDG Germán Diago wrote:
Hello. I'm working with boost::any and shared_ptr.
I'm implementing a plugin system which uses registration from .so files (under Linux). The problem is that I have a factory function which returns boost::any. This boost::any object holds a pointer type. The problem is that when I try to get the registered type back to its real type through boost::any_cast, the cast always fails. If I register this type in the same executable as the application, everything is ok, and I can cast back to its real type.I have no idea why this happens:
https://svn.boost.org/trac/boost/ticket/754 In Christ, Steven Watanabe
Very helpful. Solved the problem. I'm using boost version 1.35. Was this corrected in boost 1.37? Thanks in advance. https://svn.boost.org/trac/boost/ticket/754
In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On Mon, Jan 12, 2009 at 12:59 PM, Germán Diago
Very helpful. Solved the problem. I'm using boost version 1.35. Was this corrected in boost 1.37? Thanks in advance.
Isn't this a problem of using the incorrect visibility options and/or dlopen flags? My plugin system (including its use of std::type_info, and including dynamic unloading) works fine on Windows and LINUX, so unless you're hitting some kind of version-specific bug, you might be doing something wrong. I am strongly against using string comparisons for std::type_info objects because A) they might not work, B) if this was the right thing to do the compiler would be doing it that way (as MSVC does), and C) it would do nothing to solve the more general problem, which has to do with symbol visibility. If your std::type_info comparison is broken, then comparing function pointers and other compiler-generated objects is broken too. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode
Hello all,
Emil Dotchevski
Isn't this a problem of using the incorrect visibility options and/or dlopen flags? My plugin system (including its use of std::type_info, and including dynamic unloading) works fine on Windows and LINUX, so unless you're hitting some kind of version-specific bug, you might be doing something wrong.
Could you please describe shortly, if your plugins are compiled with specific visibility options and how you load them (dlopen flags e.g.)? I also encountered the reported problem. My plugin system here uses the dlopen flag RTLD_LOCAL in order keep plugins separated. Some other support libraries for loading shared objects e.g. libtldl might not support specifying this flag to RTLD_GLOBAL. One quick solution is: use from any.hpp unsafe_any_cast instead of any_cast Note that the signature is different; e.g. use boost::any b; ... MyClass* pClass = boost::unsafe_any_cast<MyClass>(&b); ... instead of: boost::any b; ... MyClass class = boost::any_cast<MyClass>(b); ... Read also the comments before unsafe_any_cast in any.hpp; in spite of the warning that this function is subject to change, it is still in boost 1.38.0 and it seems to be still used by boost::signal.
I am strongly against using string comparisons for std::type_info objects because A) they might not work, B) if this was the right thing to do the compiler would be doing it that way (as MSVC does), and C) it would do nothing to solve the more general problem, which has to do with symbol visibility. If your std::type_info comparison is broken, then comparing function pointers and other compiler-generated objects is broken too.
A) is it due to different name mangling? B) gcc seems to do it since some time for performance reasons C) IMHO, function pointers and other stuff might not be interesting when just one wants to get boost::any to work across library borders. Best regards, Uli
On Wed, Feb 25, 2009 at 1:20 AM, Ulrich Türk
Emil Dotchevski
writes: Isn't this a problem of using the incorrect visibility options and/or dlopen flags? My plugin system (including its use of std::type_info, and including dynamic unloading) works fine on Windows and LINUX, so unless you're hitting some kind of version-specific bug, you might be doing something wrong.
Could you please describe shortly, if your plugins are compiled with specific visibility options and how you load them (dlopen flags e.g.)?
Yes, I'm using RTLD_GLOBAL.
I also encountered the reported problem. My plugin system here uses the dlopen flag RTLD_LOCAL in order keep plugins separated. Some other support libraries for loading shared objects e.g. libtldl might not support specifying this flag to RTLD_GLOBAL.
If you want certain symbols in a .so to not be visible, you can make them invisible when you build the .so; dlopen would still see everything else, including the important compiler-generated stuff like type_info objects and vtables. Reducing the visible symbols in a .so could also reduce its size.
I am strongly against using string comparisons for std::type_info objects because A) they might not work, B) if this was the right thing to do the compiler would be doing it that way (as MSVC does), and C) it would do nothing to solve the more general problem, which has to do with symbol visibility. If your std::type_info comparison is broken, then comparing function pointers and other compiler-generated objects is broken too.
A) is it due to different name mangling?
A) Is due to the C++ standard not guaranteeing you anything about what .name() returns. A standard-conforming compiler could strip out all names and return "n00b" for every type name.
B) gcc seems to do it since some time for performance reasons
All I'm saying is that operator== is the right way to compare std::type_info objects. I don't know if the only motivation for the exact behavior of operator== is performance, but I don't feel qualified to suggest to the GCC team to change it (which would be the right "fix", assuming there is a problem to fix.)
C) IMHO, function pointers and other stuff might not be interesting when just one wants to get boost::any to work across library borders.
What about virtual function table pointers? What about the rest of the
RTTI system? Would dynamic_cast
participants (4)
-
Emil Dotchevski
-
Germán Diago
-
Steven Watanabe
-
Ulrich Türk