跨dll边界的内存分配和释放 [英] Memory allocation and deallocation across dll boundaries

查看:21
本文介绍了跨dll边界的内存分配和释放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道在一个 dll 中进行的内存分配然后在另一个 dll 中释放会导致各种问题,尤其是关于 CRT.在导出 STL 容器时,这类问题尤其成问题.我们以前遇到过这类问题(在编写与我们的库链接的自定义 Adob​​e 插件时),我们已经通过定义我们在所有容器中使用的自己的分配器来解决这些问题,例如:

I understand that memory allocations made in one dll then subsequently free'd in another can cause all sort of problems, especially regarding the CRT. These sorts of problems are especially problematic when it comes to exporting STL containers. We've experienced these sorts of problems before (when writing custom Adobe plugins that linked with our libraries) and we've worked round these issues by defining our own allocator that we use in all our containers, eg:

typedef std::vector < SessionFields, 
        OurAllocator < SessionFields > > 
        VectorSessionFields;

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

这在向/从我们的代码传递类型时效果很好,但是我们遇到了一个问题,因为我们现在必须调用 Adob​​e SDK 中的一个函数,该函数返回一个填充的向量,当它消失时会导致崩溃范围.

This has worked well when passing types to/from our code, however we've hit a problem in that we're now having to call a function in Adobe's SDK that returns a populated vector which causes a crash when it goes out of scope.

显然,当它最终在我的代码中被释放时,内存被分配到属于不同堆的 Adob​​e SDK 中是一个问题.所以我想也许我可以做一些聪明的事情,比如以某种方式覆盖或导出他们 SDK 中使用的分配器,这样我就可以用它来清理从他们的函数返回的容器.

Obviously, it's a problem with memory being allocated in Adobe's SDK belonging to a different heap when it's finally free'd in my code. So I'm thinking that maybe I could do something clever like somehow overriding or exporting the allocator used in their SDK so I could use it to clean up containers returned from their functions.

我也在考虑编写一个包装器或某种类型的 thunking 层,以便在我的代码和 SDK 之间安全地编组 STL 容器(虽然这听起来很混乱).

I'm also looking at writing a wrapper or some sort of thunking layer whereby STL containers would be safely marshalled between my code and the SDK (although this does sound very messy).

或者,我也在考虑使用 GetProcessHeaps 来识别 SDK 中使用的堆,并尝试针对此堆而不是默认堆进行释放.

Alternatively, I'm also looking at using GetProcessHeaps to identify the heap used from within the SDK, and try to free against this heap, instead of the default heap.

有人对我们如何解决这个问题有任何建议吗?

Has anyone any advice on how we can solve this problem?

推荐答案

具有讽刺意味的是,Adobe 源库有一个 adobe::capture_allocator 类专门针对此类 DLL 安全性编写.它的工作方式是在它被实例化时捕获本地 newdelete,并在对象的生命周期内携带它们.(有关如何执行此操作的详细信息,请参阅 adobe::new_delete_t,尤其是此处的实现.)使用捕获的delete<进行释放/code> 例程,保证无论您身在何处都可以使用正确的 delete 进行删除.

Ironically enough, the Adobe Source Libraries has a adobe::capture_allocator class that was written specifically with this kind of DLL safety in mind. The way it works is to capture the local new and delete at this point it is instantiated, and to carry them both around for the lifetime of the object. (See adobe::new_delete_t for details on how it does this, especially the implementation here.) Deallocations take place with the captured delete routine, guaranteeing that no matter where you are you are deleting with the proper delete.

您可以看到在整个 version_1 中使用的 capture_allocator> Adob​​e 源库中的类型,例如 adobe::any_regular_tadobe::copy_on_write.capture_allocator 也应该与所有 STL 容器类型兼容.

You can see capture_allocator used throughout the version_1 types in the Adobe Source Libraries, such as adobe::any_regular_t and adobe::copy_on_write. capture_allocator should be compatible with all STL container types as well.

更新:capture_allocator 不符合标准,因为它保留了状态.这不应成为其可用性的大障碍,但这确实意味着不能保证其使用符合标准的容器.

Update: capture_allocator is not standard-compliant because it retains state. This should not be a big hindrance to its usability, but it does mean its use is not guaranteed to work with standard-compliant containers.

这篇关于跨dll边界的内存分配和释放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆