[boost.serialization] shared object plugin
Hi together, inside the application I'm writing is defined a base class and a factory for the creation of instances through a number of plugins. The plugins auto registers when theis shared objects are dynamically loaded from the application. Each plugin instance is derived from a pure abstract interface defined in the application and used from the plugins through an header. The application maintains a list of these plugins as a member of an object. I would like use boost.serialization library in order to serialize the application container object with all the plugins contained. The library reference mentions a plugin case among its 'special considerations', but I couldn't obtain nothing working till now, so that I wonder if I should use instead the 'PIMPL' idiom (mentioned in the 'Case Studies'). I'm neither sure if the PIMPL idiom is the right waym since it would imply the definition of the base class in every plugin (so in every shared object), that means a replication of the same coding. So far, is there a complete example of boost.serialization of plugins with private implementation in shared object? Many thanks in advance Giampiero
Giampiero Gabbiani wrote:
So far, is there a complete example of boost.serialization of plugins with private implementation in shared object?
There are some tests and demo for this case. Have you checked in the libs/serialization/test and libs/serialization/example directories? Robert Ramey
Hi Robert,
I tried the test_dll_plugin (with CMAKE under Linux) that seems to cover my
case.
add_executable(test_dll_plugin test_dll_plugin.cpp polymorphic_base.cpp)
target_link_libraries(test_dll_plugin dl boost_serialization
boost_filesystem)
add_library(plugin_polymorphic_derived2 SHARED polymorphic_derived2.cpp)
it compiles (under Linux) but during execution I get:
test_dll_plugin: /usr/include/boost/serialization/singleton.hpp:137: static
T& boost::serialization::singleton<T>::get_mutable_instance() [with T =
boost::archive::detail::extra_detail::guid_initializer
Giampiero Gabbiani wrote:
So far, is there a complete example of boost.serialization of plugins with private implementation in shared object?
There are some tests and demo for this case. Have you checked in the libs/serialization/test and libs/serialization/example directories?
Robert Ramey
Hi Giamperio unless you have mismatched your Cmake linking directives (I guess it is not the case), maybe you should tell us more about the gcc version you use. it seems some recent gcc versions (>=4.6) have a new linking model and dll linkage is done only if some code is explicitely recognized in your own dll or executable. Some hints to fix such issue : - invoke a dlopen call on the missing linked dll in your executable or at loading of your own dll - add some static code that explicitely uses some resources from the missig dll however these are just hints... maybe nothing to do with your pb. just in case it could help you. regards frc -- Le 08/08/2012 08:41, Giampiero Gabbiani a écrit :
Hi Robert, I tried the test_dll_plugin (with CMAKE under Linux) that seems to cover my case.
add_executable(test_dll_plugin test_dll_plugin.cpp polymorphic_base.cpp) target_link_libraries(test_dll_plugin dl boost_serialization boost_filesystem)
add_library(plugin_polymorphic_derived2 SHARED polymorphic_derived2.cpp)
it compiles (under Linux) but during execution I get:
test_dll_plugin: /usr/include/boost/serialization/singleton.hpp:137: static T& boost::serialization::singleton<T>::get_mutable_instance() [with T = boost::archive::detail::extra_detail::guid_initializer
]: Assertion `! is_locked()' failed. If I make an ldd of both the executable
ldd test_dll_plugin linux-vdso.so.1 => (0x00007fff0d56d000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f547aaab000) libboost_serialization-1_49.so.1.49.0 => /usr/lib64/libboost_serialization-1_49.so.1.49.0 (0x00007f547a835000) libboost_filesystem-1_49.so.1.49.0 => /usr/lib64/libboost_filesystem-1_49.so.1.49.0 (0x00007f547a610000) libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/libstdc++.so.6 (0x00007f547a301000) libm.so.6 => /lib64/libm.so.6 (0x00007f547a07d000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f5479e66000) libc.so.6 => /lib64/libc.so.6 (0x00007f5479ad4000) libboost_system-1_49.so.1.49.0 => /usr/lib64/libboost_system-1_49.so.1.49.0 (0x00007f54798d0000) /lib64/ld-linux-x86-64.so.2 (0x00007f547acaf000)
and the shared object
ldd libplugin_polymorphic_derived2.so linux-vdso.so.1 => (0x00007fffd332b000) libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/libstdc++.so.6 (0x00007ffa4936c000) libm.so.6 => /lib64/libm.so.6 (0x00007ffa490e7000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007ffa48ed0000) libc.so.6 => /lib64/libc.so.6 (0x00007ffa48b3e000) /lib64/ld-linux-x86-64.so.2 (0x00007ffa498fa000)
the strange is that there is no dynamic linking to libboost_serialization inside the libplugin_polymorphic_derived2.so.
So ... did I make some error in the project organization or are there any comile option or define I missed?
I wonder - for example - if I should link the executable against the multithread version of the serialization library (I guess not ...).
Many thanks Giampiero
Giampiero Gabbiani wrote:
So far, is there a complete example of boost.serialization of plugins with private implementation in shared object?
There are some tests and demo for this case. Have you checked in the libs/serialization/test and libs/serialization/example directories?
Robert Ramey
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Giampiero Gabbiani wrote:
Hi Robert, I tried the test_dll_plugin (with CMAKE under Linux) that seems to cover my case.
add_executable(test_dll_plugin test_dll_plugin.cpp polymorphic_base.cpp) target_link_libraries(test_dll_plugin dl boost_serialization boost_filesystem)
add_library(plugin_polymorphic_derived2 SHARED polymorphic_derived2.cpp)
it compiles (under Linux) but during execution I get:
test_dll_plugin: /usr/include/boost/serialization/singleton.hpp:137: static T& boost::serialization::singleton<T>::get_mutable_instance() [with T = boost::archive::detail::extra_detail::guid_initializer
]: Assertion `! is_locked()' failed.
OK - I looked into this. The key facts are: I included code assertions which check that all static structures are initialized before main() is called. I did this to make sure detect any thread safey issues that might crop up of archives are created on separate threads. This code guarentees that the global static list of serializable types is not messed with from different threads. I did it this way as I didn't want to guard all the serialization calls to check this structure with locks - which would be a performance killer. BUT, this presumes that all DLLs which use the table are loaded BEFORE main is called. This the most common case, but it conflicts with our usage case. Your usage case is a very important one however and it must be supported. And it should be used much more often. I'm amazed, surprised, and disappointed that no one has spotted this before. Soooooo a) just comment out the assertion in your header. b) think about this some more. c) create a track item for this issue describing the problem and proposing a better solution. Something like calling some "other" function to turn off the assertion. Robert Ramey
Robert Ramey wrote:
Giampiero Gabbiani wrote:
Hi Robert, I tried the test_dll_plugin (with CMAKE under Linux) that seems to cover my case.
add_executable(test_dll_plugin test_dll_plugin.cpp polymorphic_base.cpp) target_link_libraries(test_dll_plugin dl boost_serialization boost_filesystem)
add_library(plugin_polymorphic_derived2 SHARED polymorphic_derived2.cpp)
it compiles (under Linux) but during execution I get:
test_dll_plugin: /usr/include/boost/serialization/singleton.hpp:137: static T& boost::serialization::singleton<T>::get_mutable_instance() [with T = boost::archive::detail::extra_detail::guid_initializer
]: Assertion `! is_locked()' failed. OK - I looked into this. The key facts are:
I included code assertions which check that all static structures are initialized before main() is called. I did this to make sure detect any thread safey issues that might crop up of archives are created on separate threads. This code guarentees that the global static list of serializable types is not messed with from different threads. I did it this way as I didn't want to guard all the serialization calls to check this structure with locks - which would be a performance killer.
BUT, this presumes that all DLLs which use the table are loaded BEFORE main is called. This the most common case, but it conflicts with our usage case. Your usage case is a very important one however and it must be supported. And it should be used much more often. I'm amazed, surprised, and disappointed that no one has spotted this before.
Soooooo
a) just comment out the assertion in your header. b) think about this some more. c) create a track item for this issue describing the problem and proposing a better solution. Something like calling some "other" function to turn off the assertion.
Robert Ramey
LOL - looked into this some more. Turns out that all my test programs call boost::serialization::singleton_module::lock() at the beginning of main(). This suggests that your system has some sort of "delayed" linking which is interesting to know. In any case, this would be an artifact of the test program rather than your application. So I would expect your application wouldn't have a problem. You can comment out the boost::serialization::singleton_module::lock() and it will make the problem go away in the test program. Note that the upshot of all this is that using the serialization library with dynamically loaded types wouldn't be thread safe even though it is for static linking. This has to be addressed if your ap is going to use multi-threading and the serialization library and dynamic linking. Robert Ramey
participants (3)
-
Francois Mauger
-
Giampiero Gabbiani
-
Robert Ramey