It looks to me that A.dll is being unloaded "too soon" or that A.dll is being loaded mulitple times. If you trap on the ctor / dtor code of extended_type_info you might be able to see what's going on. If A.DLL is being loaded automatically on using B.DLL or C.DLL it may well be unloaded automatically "too" soon. Or they maybe multiple copies and the "wrong one" gets dropped from the global tables when one DLL is unloaded. As I've said before - this is a murky area. I may experiment with if I can find the time but I need a good (complete self-contained) test case. Robert Ramey Topi Mäenpää wrote:
I got the dynamic library stuff work for a while. But now I'm getting a segmentation fault with the following setup.
As before, I have class A defined in a dll, say A.dll. This is a library I link against in other dlls and in the main executable. I also have two other libraries, B.dll and C.dll that both include definitions for many classes derived from A. Let us call these B1, B2, ... and C1, C2 ..., respectively. I'm registering the classes in the dlls with BOOST_CLASS_EXPORT. B.dll and C.dll use the definition of A in A.dll so that only a single definition of A should be present. The main executable links against A.dll and loads B.dll and C.dll at run time.
With this setup, serialization goes fine if I only use classes defined in either of the dynamically loaded libraries:
// create_in_dynamic_library_{b,c} are function pointers to dll // functions
A* b1 = (A*)create_in_dynamic_library_b("B1"); A* b2 = (A*)create_in_dynamic_library_b("B2"); A* c1 = (A*)create_in_dynamic_library_c("C1"); A* c2 = (A*)create_in_dynamic_library_c("C2");
ar & b1 & b2; //works fine ar & c1 & c2; //works fine
ar & b1 & c1; //crashes ar & c2 & b2; //crashes
In other words, I cannot serialize classes defined and exported in different dlls. Only the first one works. The segmentation fault is caused by line 213 in extended_type_info.cpp.
extended_type_info::type_info_key_cmp(const extended_type_info & rhs) const { if(type_info_key == rhs.type_info_key) // <---- this == 0! return 0;
My debugger reports that "this" is zero. This happens just after boost::serialization::base_object<A>(*this) is called in the serialize member of class {B,C}{1...N}.
I'm stuck. Any suggestions?
-Topi-
Robert Ramey wrote:
This problem has been reported by Martin Ecker. The easy fix is to just permit multiple definitions of the same virtual functions in different DLLs. This has eliminated the symptom for this user.
I didn't quite get this. What do you mean by permitting multiple definitions? How is it done?
I'm concerned that this won't really work in the general case.
I would be prefer to: a) trap attempts at multiple registrations of the same class as errors. b) explain how to avoid these situtations in the first place.
I'm kind of stuck on b). It seems to me that if A (base) is in a DLL and B(derived) is in an executable, there should be no multiple definitions of B. But the brief description of this user's case seems to suggest that this isn't the case - though without more information one can't be sure.
Robert Ramey