Re: [Boost-users] [Boost][serialization] Serialization and DLLs
I have a suggestion, please comment. The problem _could_ be in that
guid_initializer isn't exported. If I register my base class in a DLL, the DLL interface does not expose the guid_initializer::instance I have created. Since my exe now doesn't know about it, it creates a new definition. The same applies to other DLLs. (This would also explain why the same code works on Linux: all symbols are automatically exported.) What if we exposed the guid_initializer struct to the DLL interface? Would it help? At least it shouldn't do any harm to export it from the exe.
That might explain the behavior. We'll look into it. I'm having problems making test which uses a dynamically loaded DLL that I can run under bjam.
No, it didn't work... I also exported the extended_type_info subclasses (_0 and _1) from my DLL, but I still encounter the same problems. The code lacks comments, and I find it difficult to study some some of the constructs. It seems that whenever I register a class, its superclasses get registered as well. The extended_type_info pointer for my common superclase is however different for each instantiation. The exe crashes due to an unhandled unregistered_cast exception thrown at oserializer.hpp:408. Thus, it seems that downcasting cannot succeed. I even modified the extended_type_info so that it always compares keys literally instead of pointers, but this has no effect. Furthermore, I changed the tkmap and ktmap multisets to sets. I assumed this could prevent multiple registrations, but it does not. Could someone point me out a way to work around this? Any temporary solution will do until the problem has been identified and fixed. Best regards, Topi
Topi Mäenpää wrote:
I have a suggestion, please comment. The problem _could_ be in that
guid_initializer isn't exported. If I register my base class in a DLL, the DLL interface does not expose the guid_initializer::instance I have created. Since my exe now doesn't know about it, it creates a new definition. The same applies to other DLLs. (This would also explain why the same code works on Linux: all symbols are automatically exported.) What if we exposed the guid_initializer struct to the DLL interface? Would it help? At least it shouldn't do any harm to export it from the exe.
That might explain the behavior. We'll look into it. I'm having problems making test which uses a dynamically loaded DLL that I can run under bjam.
No, it didn't work... I also exported the extended_type_info subclasses (_0 and _1) from my DLL, but I still encounter the same problems.
The code lacks comments, and I find it difficult to study some some of the constructs. It seems that whenever I register a class, its superclasses get registered as well.
I'm not sure what code we are refering to but in any case I believe you are using VC 7.1 as am I. In this case it should be easy to run the code under the debugger an trap the registration to see where its getting called from.
The extended_type_info pointer for my common superclase is however different for each instantiation. The exe crashes due to an unhandled unregistered_cast exception thrown at oserializer.hpp:408. Thus, it seems that downcasting cannot succeed. I even modified the extended_type_info so that it always compares keys literally instead of pointers, but this has no effect. Furthermore, I changed the tkmap and ktmap multisets to sets. I assumed this could prevent multiple registrations, but it does not.
Note that the current version checked into the next release branch has this change. It seems that we're not using the same code.
Could someone point me out a way to work around this? Any temporary solution will do until the problem has been identified and fixed.
You might benefit by downloading the latest - and hopefully soon to be released version. 1.33.1 (RC_1_33_0). we would have a better basis for comparing. Robert Ramey
Best regards, Topi
Debugging continues...
No, it didn't work... I also exported the extended_type_info subclasses (_0 and _1) from my DLL, but I still encounter the same problems.
The code lacks comments, and I find it difficult to study some some of the constructs. It seems that whenever I register a class, its superclasses get registered as well. The extended_type_info pointer for my common superclase is however different for each instantiation. The exe crashes due to an unhandled unregistered_cast exception thrown at oserializer.hpp:408. Thus, it seems that downcasting cannot succeed. I even modified the extended_type_info so that it always compares keys literally instead of pointers, but this has no effect. Furthermore, I changed the tkmap and ktmap multisets to sets. I assumed this could prevent multiple registrations, but it does not.
void_caster_registry does not contain valid entries. Whenever a base-derived relationship crosses a DLL boundary, the correct pair isn't inserted to the registry. Instead, the extended_type_info for the base class points to a different object than the extended_type_info of the real base class. Since the base class isn't exported in the exe/other dll, there is no object key, and the extended_type_info objects cannot be matched with them (I have changed the comparison operator to match the keys because the pointers won't match anyway.) Could this be related to the fact that the low-level type_info pointer for the classes is different in the dll and the exe? (This is also the reason why dynamic_cast doesn't work across dynamic library boundaries.) Is it possible to use the non-rtti versions with MSVC 7.1?
Could someone point me out a way to work around this? Any temporary solution will do until the problem has been identified and fixed.
I have dug deep into the library but have not been able to identify the problem. I'm getting a bit frutsrated... Any help will be appreciated. -- Topi Mäenpää CTO, Intopii +358 40 774 7749
Topi Mäenpää wrote:
Debugging continues...
Could this be related to the fact that the low-level type_info pointer for the classes is different in the dll and the exe?
That sounds like it could explain this.
(This is also the reason why dynamic_cast doesn't work across dynamic library boundaries.)
I've never heard of this before. If this is true it would be key indicator that something's wrong. Is this a known MSVC bug? That would be very interesting to know. Is it possible to use the non-rtti versions with MSVC
7.1?
I have implemented non-rtti version which is documented and tested - test_non_rtti. The test verifies that types which are identified with different runtime typing systems can inter-operate. The library includes extended_type_info_no_rtti.cpp (a mis-nomer I see now). This runtime typing system uses the BOOST_CLASS_EXPORT key as the type identifier. So to use this you'll have to fix the "type_info_implementation" trait for this type and besure its exported. This hasn't really been used except in the testing (as far as I know). As far as using it a derived class defined in a DLL where the base class is in some other library? I reviewed the relevant code and have verified that the serialization system presumes that type_info returns the same value regardless of whether the type is implemented within a an executable, standard library or dll. I can't imagine why it would be any other way. I also don't have any other reports of this. Of course, this is not a common usage so that probably doesn't mean much. Double check that that there aren't any differences in things like _cdecl etc. Maybe that might explain why the run-time type signatures vary depending up where the type is implemented. I've started written my own test of this situation but its kind of hung up in some in trying to get it worked into bjam. So I haven't finished it.
Could someone point me out a way to work around this? Any temporary solution will do until the problem has been identified and fixed.
see above.
I have dug deep into the library but have not been able to identify the problem. I'm getting a bit frutsrated... Any help will be appreciated.
I'll do what I can. Robert Ramey
participants (2)
-
Robert Ramey
-
Topi Mäenpää