c – 释放DLL创建的对象
发布时间:2020-12-16 07:06:48 所属栏目:百科 来源:网络整理
导读:我的DLL加载了LoadLibrary – 他们仍然可以共享运行时,还是我必须确保在分配的同一个DLL中删除对象? 在我的示例中,我有一个在DLL模块中实现的公共基类,然后由Lua对象镜像,Lua确定其生命周期.因此,当Lua垃圾收集器决定这样做时,我需要释放该对象,并且我无法
我的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运行时进行编译,并且名称保持不变. 我猜它看起来像: // 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 header class 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; }; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |