Jump to content
  • Advertisement
Sign in to follow this  
CTar

Passing std::string over DLL boundaries

This topic is 4836 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 understand that you shouldn't be passing STL types(std::vector, std::list) over DLL boundaries, one thing I have wondered about was if this also mean that you shouldn't use: "const std::string&" for parameters. Does it mean you have to use a c-style string(char*)?.

Share this post


Link to post
Share on other sites
Advertisement
I would use them as parameters. The compiler generates a warning, but it doesn't matter if you intend that the program using the dll will use std::string. I disable the warning with:

#pragma warning(disable : 4251) // disable string warnings

Share this post


Link to post
Share on other sites
You should be able to get away with passing STL containers across DLL boundaries if you use the multithreaded DLL runtime library. I'm not entirely sure of the effects that might have on performance, so you might want to research it a bit before merely applying it as a quick (possibly hackish) fix, but the basic idea I believe is that it causes the DLL and your process to share the same heap, rather than have two distinct heaps. Thus, when memory is newed on one side, and deleted on the other, things crash and burn when there are two actual heaps, but work normally when there's only one.

With that in mind, I can't see why references would cause a problem, since the destructor would never be called on the containers on the opposite side of the DLL boundary from where the constructor was called.

Well, I take that back, partially. resize() and similar functions would very likely call new or delete, so a non-const reference would be bad. And even with a const reference, you're not guaranteed that some members are declared mutable, so even if you think that nothing should be newed ordeleted, something very well could be.

Share this post


Link to post
Share on other sites
If all else fails, you can use const char* across the boundary, and std::string everywhere else.

Share this post


Link to post
Share on other sites
over dll boundaries should not matter - it's when you are going between different processes you have to worry about marshalling.

Share this post


Link to post
Share on other sites
Quote:
Original post by paulecoyote
over dll boundaries should not matter - it's when you are going between different processes you have to worry about marshalling.


Generally dll's have a different heap and free-store from the main exe.

Share this post


Link to post
Share on other sites
Yeah STL using across dll's. Its a tough one. Depending on what you are doing it can be ok. Typically I would consider passing Microsoft STL across dll boundaries generally a no no. Yes it works...but I would argue that for the general case you are getting lucky. Agony brings up a good point about the new/deletion of internal container objects. Another issue that by ignoring the 4251 warning you aren't necessarily exporting the entire interface to your class correctly. Again not always a problem but can lead to some tricky bugs if it is a problem. I also seem to remember reading up on a problem with MS's implemenation and their use of static variables for reference counting, or holding onto pointers for quick reuse, something like that. If you really want to export STL across dll boundaries I would suggest building in STLPort into your program. As far as I can tell and from what I've read in their forum and FAQ they don't have necessarily all the possible problems the Microsoft implementation does. It is however, a very active code base and does have bugs just like any other GNU/Freeware/Open Source project. They don't always have the QA resources their counterparts do and sometimes you have to wait a bit to get a fix. Anyway...my 2 cents...take it for what its worth.

Share this post


Link to post
Share on other sites
Quote:
Original post by Shannon Barber
Quote:
Original post by paulecoyote
over dll boundaries should not matter - it's when you are going between different processes you have to worry about marshalling.


Generally dll's have a different heap and free-store from the main exe.


That is inaccurate. When a DLL is loaded, it shares the same free store as the process that loaded it. This only makes sense, if you think about it, because the DLL is just code, and that code is being run from your executable, hence, it must share the same memory space as your process.

The reason for this misconception that DLLs have a separate heap is that on Windows, if you don't use the same runtime library for both the executable and the DLL, they won't be sharing the same free-store because those libraries are not internally sharing the same data structures. However, if you use Multithraded DLL in both the executable and the DLL, it works fine. You can allocate memory in the DLL, free it in the executable code, and there are no memory leaks... I tried it.

Quote:
over dll boundaries should not matter - it's when you are going between different processes you have to worry about marshalling.


There *is* actually one reason you could want to avoid passing any standard data type accross DLL boundaries. That reason is that if the DLL code is compiled from another compiler, it might use a *different implementation* of those objects. This means they might not internally use the same variables, which would result in unpredictable consequences (most likely a crash).

However, if you are compiling all the DLLs yourself, along with your main program, and you are using the same compiler for each, then there shouldn't be any problems. I am doing it myself, and it works fine.

Share this post


Link to post
Share on other sites
Quote:

That is inaccurate. When a DLL is loaded, it shares the same free store as the process that loaded it.


Nope. Never has been like this, but I was curious to your claims, so I tried it in my program just to see what happens. I malloc'd in one DLL and free'd in another.
Everything was compiled with Multithreaded DLL.

CRASH.

So how are you achieving what you are claiming? I am really curious...

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!