Jump to content
  • Advertisement
Sign in to follow this  
GenuineXP

Safety of Passing STL Objects vs. Boost Objects Across Binaries

This topic is 3801 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm still working with plugin details and design, and I'm wondering just how dangerous it is to pass around Boost objects versus STL objects. I know that passing around STL objects like std::vector is dangerous because different implementations will clash and cause major problems (i.e., your program crashes). I also realize that passing any non-POD type between binaries can be tricky, but I'll have to endure that fact... I'm working with plugins, after all. The Boost implementation is always the same (except between different releases, of course). I would imagine this makes it significantly safer to pass around a Boost.Iostreams object than an std::map, since the map has about ten implementations floating around and the Boost.Iostreams library has one. Is this true? I would like to avoid having to work with a purely C interface (I already do in the form of C object adapters, so that plugins can be implemented in C as well... but I'd like this to be a totally separate case). Converting std::string and std::vector to and back from C isn't too hard, but other constructs can get very hard to work with (correctly). In the end, I don't mind so much if passing Boost stuff back and forth means that sometime recompilation is necessary, so long as it isn't always needed. I think it may be worth the cleaner interface. But just how unsafe would this be? Thanks.

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by GenuineXP

The Boost implementation is always the same (except between different releases, of course). I would imagine this makes it significantly safer to pass around a Boost.Iostreams object than an std::map, since the map has about ten implementations floating around and the Boost.Iostreams library has one. Is this true?


There is no ABI(application binary interface) for C++ that means any object not compiled with the identical compiler is not portable in an way, shape or form. Hence the reason C++ libraries either come as source or you have to down load and use the one built for your compiler. boost compiled with gcc may as well have come from different source when compared to boost built with VC it will not be compatible.

here is a link that describes the difficulties you will encounter.
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=180

Share this post


Link to post
Share on other sites
Quote:
Original post by stonemetal
Quote:
Original post by GenuineXP

The Boost implementation is always the same (except between different releases, of course). I would imagine this makes it significantly safer to pass around a Boost.Iostreams object than an std::map, since the map has about ten implementations floating around and the Boost.Iostreams library has one. Is this true?


There is no ABI(application binary interface) for C++ that means any object not compiled with the identical compiler is not portable in an way

Yes, but I'm thinking more along the lines of could it be unsafe if compiled with the same compiler but simply on a different computer (or even a different platform using a cross compiler such as mingw32).

In regards to the STL, problems can arise on the same platform with the same compiler vendor and version simply because the STL implementation was different. Could this sort of thing occur with Boost (other than using different incompatible versions)? I don't know much about how Boost is distributed, so I don't really know if there exists alternate versions or numerous incompatibilities between versions, etc.

The goal is to be able to compile a plugin using the same compiler (same vendor... hopefully different versions won't screw things up too often) on the same platform and distribute them. So, a user running Ubuntu (x86) could compile a plugin, send it to another Ubuntu (also x86) user, and they can just install it and go. Same case for Windows, of course.

Thanks for the input. :-)

Share this post


Link to post
Share on other sites
Even if the implementation was identical, if any of the relevant compiler settings differ, it will crash. You're going to have to provide the complete build environment if you want to guarantee binary compatibility.

Share this post


Link to post
Share on other sites
As people have already stated this is going to be fraught with crashes and other issues across platform even when everything is built using the same compiler on the same platforms.

A better option would be to pass only POD types across the DLL boundaries. I.e. Pass only int32, bool, float, double, double *, etc. You can still write your DLLs using boost/STL _internally_ you just don't pass those values across the boundaries themselves.

It _might_ also be ok to pass structs of PODs across the DLLs boundaries as long as there's no padding, or rather, as long as the padding is consistent between the calling application and the compiled DLL.

In summary, stick to POD types or pointers to POD types ONLY. You'll save yourself a world of hurt.

Andy

Share this post


Link to post
Share on other sites
Hm, this could prove to be very detrimental. However, I compiled plugins on different physical machines and they all loaded and executed properly on another machine (same OS, same compiler vender, and same compiler version). I figured I would have to bundle binaries for different platforms.

Am I really saving myself anything by passing POD types only? It seems that I'd have to compile for specific platform/STL/vendor/version/etc. anyway! If that's the case (or would often be), why not just go nuts and pass STL and Boost object around like crazy?

The big problem is interoping between C and C++ too. If I want to use Boost.Iostreams, for example... how in the world do I go from the engine interface (that clients see) which uses stream objects, into C, across the border, and back into stream objects again? This seems to undermine using a library like this is the first place.

I based much of my plugin system on this article from Dr. Dobb's (I've been making some changes though, of course). It outlines the common problems and I get the impression that its design solves at least some of them... but the author doesn't seem to flat out state whether it does or not. There's no, "As you can see, this framework solves X, Y, and Z!" Oh well.

In the end, recompilation is probably just how it has to be. Stupid name mangling. :-P

Thanks!

Share this post


Link to post
Share on other sites
Quote:
Original post by GenuineXP
Am I really saving myself anything by passing POD types only? It seems that I'd have to compile for specific platform/STL/vendor/version/etc. anyway! If that's the case (or would often be), why not just go nuts and pass STL and Boost object around like crazy?


If you reduce things down to POD types which are the same on each platform, then you can reconstruct the complex types from those on each side. This is no different from sending data over the network from one PC to another, except it is probably slightly easier than breaking it right down to the byte stream level.

Quote:
I based much of my plugin system on this article from Dr. Dobb's (I've been making some changes though, of course). It outlines the common problems and I get the impression that its design solves at least some of them... but the author doesn't seem to flat out state whether it does or not. There's no, "As you can see, this framework solves X, Y, and Z!" Oh well.


Have you read all the articles in the series? There seems to be a lot of info and maybe some of that will clear things up.

Share this post


Link to post
Share on other sites
It may not be 'performant', but all of your troubles may be resolved by a serialization layer. Serialize/deserialize on each side of the boundary. Boost::serialization should provide this functionality - even if each side is not binary compatible, the serialization streams will be if compiled from compatible versions of boost.

Edit: Kylotan basically already said it.

Honestly I think something like this is your best bet, it would all but eliminate the frustration and headache associated with this task.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!