Allocating and freeing memory over dll boundaries

I understand that allocating memory in one dll and then free in another can cause all kinds of problems, especially with respect to CRTs. Similar problems are especially problematic when it comes to exporting STL containers. Previously, we encountered similar problems (when writing custom Adobe plugins associated with our libraries), and we worked on these problems by defining our own dispenser that we use in all our containers, for example:

typedef std::vector < SessionFields, OurAllocator < SessionFields > > VectorSessionFields; typedef std::set < SessionFields, std::less < SessionFields >, OurAllocator < SessionFields > > SetSessionFields; 

This works well when passing types to / from our code, however we are faced with the problem that now we need to call a function in the Adobe SDK that returns a populated vector that causes a crash when the region exits.

Obviously, the memory issue is highlighted in the Adobe SDK owned by another heap when it finally freed up in my code. So I think that maybe I could do something smart, somehow redefine or export the dispenser used in their SDK so that I can use it to clean the containers returned from their functions.

I also look at creating a wrapper or some kind of thunking layer in which the STL containers will be safely distributed between my code and the SDK (although this sounds very dirty).

Alternatively, I also consider using GetProcessHeaps to determine the heap used in the SDK, and try to free it from this heap instead of the default heap.

Does anyone have any tips on how we can solve this problem?

+7
c ++ memory-management malloc dll stl
source share
3 answers

Oddly enough, in the Adobe Source libraries there is an adobe::capture_allocator , which was specially written taking into account such DLL security. The way it works is to capture the local new and delete on which it was created, and transfer them as the lifetime of the object. (For more information, see adobe::new_delete_t , especially when implemented here .) Cancellation occurs using the captured delete procedure, which ensures that no matter where you are, you delete the correct delete .

You can see capture_allocator used in all version_1 types in Adobe source libraries such as adobe::any_regular_t and adobe::copy_on_write . capture_allocator must also be compatible with all types of STL containers.

Update: capture_allocator does not comply with the standard because it saves state. This should not be a big obstacle to its usability, but it means that its use is not guaranteed to work with standard containers.

+6
source share

We are currently working on a dll that provides C ++ functionality through the C interface (so that C # can use the specified DLL).

for example: dll has the structure myStruct_s, the interface provides the following functions:

interface.h

 #ifndef INTERFACE_TYPES_H # error Please include interace_types.h #endif myStruct_s * CreateTheStruct() { return new myStruct_s(); } void DestroyTheStruct(myStruct_s * the_struct) { delete the_struct; } void DoSomethingToTheStruct(myStruct_s * the_struct); 

interface_types.h

 #define INTERFACE_TYPES_H struct myStruct_s; // fwd declaration #endif 

interface.cpp

 #if defined(__CPPPLUS) || defined(__cplusplus) || defined (__CPLUSPLUS) #include<TheRealFileContainingTheRealMyStruct_s.h> // handle the .h functions here #endif 

comeOutsideCppFile.cpp

 #include "interface_types.h" #include "interface.h" void main() { myStuct_s * x = CreateTheStruct; DoSomethingToTheStruct(x); DestroyTheStruct(x); } 

The above brief description of how our material works, basically: Regardless of what the dll should look like: Created, Processed, Destroyed dll-side

This code is not 100% accurate !!!

Also, keep in mind that if you are using pure C ++ dll, you probably need the same compiler with the same settings as for building the dll.

+2
source share

You can try to see if there are any formal C ++ rules for what happens when an exception is thrown into one DLL and gets into another, and then goes out of scope - it seems very similar. For exceptions, I think you should provide the copy constructor with a special signature, although I'm not sure what exactly right now.

0
source share

All Articles