c – 释放DLL创建的对象

c – 释放DLL创建的对象,第1张

概述我的DLL加载了LoadLibrary – 他们仍然可以共享运行时,还是我必须确保在分配的同一个DLL中删除对象? 在我的示例中,我有一个在DLL模块中实现的公共基类,然后由Lua对象镜像,Lua确定其生命周期.因此,当Lua垃圾收集器决定这样做时,我需要释放该对象,并且我无法预测将从哪个DLL中进行垃圾回收. 我在想每个DLL都有以下函数的副本: int ReleaseObject(lua_St 我的DLL加载了Loadlibrary – 他们仍然可以共享运行时,还是我必须确保在分配的同一个DLL中删除对象?

在我的示例中,我有一个在DLL模块中实现的公共基类,然后由Lua对象镜像,Lua确定其生命周期.因此,当Lua垃圾收集器决定这样做时,我需要释放该对象,并且我无法预测将从哪个DLL中进行垃圾回收.

我在想每个DLL都有以下函数的副本:

int ReleaSEObject(lua_State* L){    // object pointer is stored in fIEld [0]    lua_rawgeti(L,-1,0);    delete (Object*) lua_touserdata(L,-1);    return 0;}

然后,指向此函数的指针将放在Metatable __gc字段中,Metatable将用于该DLL中定义的派生类的所有实例.这足以保证安全删除吗?

解决方法 考虑在dll的客户端上使用std :: unique_ptr或std :: shared_ptr(使用自定义删除器调用ReleaSEObject),这些可以正确地处理跨dll边界删除.

另外,将dll接口完全保持为“C”是一个很好的做法,这样dll就可以使用不同的c运行时进行编译,并且名称保持不变.
不是从dll继承基类实现,而是导出BaseImpl * CreateBaseImpl();
voID DeleteBaseImpl(BaseImpl *);
这对函数让它们返回一个指向你需要的实现的指针.然后该指针应该被送到您选择的智能指针.使BaseImpl的公共接口仅使用原始类型(句柄,数字,指向这样的指针,C数组 – 好; stl容器 – 不好:创建cpp运行时依赖性)

我猜它看起来像:

// code using LUA - unconcerned with the cross-dll nature of the implementation...{    auto p = new ConcreteImpl(); // pass p to LUA as you normally would    ...    // when LUA wants it deleted:    delete p;    p = nullptr;    // probably tell LUA it was deleted}...
// BaseImpl.h - Dll Interface  headerclass BaseImpl;extern "C" BaseImpl * CreateBaseImpl();extern "C" voID DeleteBaseImpl(BaseImpl *p);
// ClIEnt code#include "BaseImpl.h"#include <type_traits>#include <memory>#include <windows.h>class ConcreteImpl { // no inheritance probably necessary{    using namespace std;    ...    ConcreteImpl()     :   m_ptrDll( ::LoadlibraryW(L"BaseImpl.dll"),&::Freelibrary ),m_ptrBase( nullptr,[](BaseImpl *){} )    {        Assert( m_ptrDll,"LoadlibraryW() Failed err=0x%x",::GetLastError() );        auto pfnCreate = reinterpret_cast<decltype(&CreateBaseImpl)>(            ::GetProcAddress(m_ptrDll.get(),"CreateBaseImpl") );        auto pfnDelete = reinterpret_cast<decltype(&DeleteBaseImpl)>(            ::GetProcAddress(m_ptrDll.get(),"DeleteBaseImpl") );        Assert( pfnCreate && pfnDelete,"GetProcAddress() Failed err=0x%x",::GetLastError() );        // use move constructor to assign new value        m_ptrBase = decltype(m_ptrBase)( pfnCreate(),pfnDelete );        Assert( m_ptrBase,"CreateBaseImpl returned nullptr" );    }    ...    // methods that use m_ptrBase go here    ...    unique_ptr<        remove_pointer<HMODulE>::type,decltype(&::Freelibrary)    > m_ptrDll;    unique_ptr<BaseImpl,decltype(&DeleteBaseImpl)> m_ptrBase;        };
总结

以上是内存溢出为你收集整理的c – 释放DLL创建的对象全部内容,希望文章能够帮你解决c – 释放DLL创建的对象所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1226999.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存