C ++:Dll卸载问题 [英] C++: Dll unloading issue

查看:185
本文介绍了C ++:Dll卸载问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何确保dll在其中存在任何对象时不卸载?

How can I ensure a dll is not unloaded while any objects in it exist?

问题是,当我使用explict内存管理时,我可以删除dll对象在释放DLL之前,但是使用智能指针我没有控制其中销毁的顺序,意味着dll可能会释放首先导致崩溃时尝试释放其他对象:

The problem is, when I was using explict memory management I could delete the dll objects before freeing the dll, however with smart pointers I have no controll over the order there destroyed, meaning the dll may be freed first causeing a crash when trying to free one of the other objects:

FlPtr是一个简单的计数类,根据需要调用AddRef和Release。

FlPtr is a simple refrence counting class thats calls AddRef and Release as needed

ExampleDll *dll = LoadDll(L"bin\\example.dll");
IObject *obj = dll->CreateObject();
...
obj->Release();
delete dll;//fine because all objects already deleted
return 0;

auto_ptr<ExampleDll> dll = LoadDll(L"bin\\example.dll");
FlPtr<IObject> obj = dll->CreateObject();
...
return 0;//crash if dll is destructed before obj since Object::Release needs to call into the dll

我试图使dll句柄自己卸载,即只有在所有对象被删除后才卸载。这个工作通过创建一个新的对象IExampleDll这个dll实现。这就像ExampleDll对象从前,但生活在dll而不是exe,也是refrence计数。 dll中的每个对象增加这个引用的引用,并在销毁时增加它。这意味着当exe释放它的refrences和所有的dlls对象已被销毁时,refrence计数只到达零。然后它会删除自己调用FreeLibrary(GetModuleHandle())在它的析构函数。

I tried making the dll handle unloading itsself, ie only unload after all objects have been deleted. This work by creating a new object IExampleDll which the dll implements. This is like the ExampleDll object from before but lives in the dll rather than the exe and is also refrence counted. Each object in the dll increments this refrence on contruction and deincrements it on destruction. This means the refrence count only reaches zero when the exe has Released its refrences AND all the dlls objects have been destroyed. It then deletes itsself calling FreeLibrary(GetModuleHandle()) in its destructor.

然而这会崩溃在FreeLibrary,im asuming,因为线程仍然在dlls代码,正在卸载...

This however crashes at the FreeLibrary, im asuming because the thread is still in the dlls code that is being unloaded...

我现在有点失落,现在如何确保dll只有卸载时没有剩余的对象,除了回去释放dll明确在其他一切应该被删除后;

I'm at a loss now how to make sure the dll is only unloaded when there are no remaining objects, apart from going back to freeing the dll explicitly after everything else should have been deleted;

int main()
{
    ExampleDll *dll = LoadDll("bin\\example.dll");
    restOfProgram();
    delete dll;
}

这种方法变得困难当dll需要加载/卸载中间程序saftly,即如果用户在选项中从d3d更改为openGL。

This approach becomes difficult when dlls need to be loaded/unloaded mid program saftly, ie if the user changed from d3d to openGL in options.

推荐答案

假设您不想在卸载库时终止线程(否则,请参阅MSalters),您需要从加载它的调用者释放库。

Assuming you do not want to terminate the thread when unloading the library (otherwise, see MSalters), you need to free the library from the caller that loaded it.

COM解决了一个in-DLL实例计数器如果我正确理解你),并通过调用全局导出的 CanUnloadNow 函数来检查它。

COM solves that by an in-DLL instance counter (much like yours, if I understand you correctly), and regulary checking it by calling a global exported CanUnloadNow function.

让你的对象/接口智能指针还引用他们来自的DLL。这将增加客户端数据大小,但您不需要触摸DLL。你甚至可以回收LoadLibrary / FreeLibrary引用计数器,但这可能会影响性能。

Another option is to have your object/interface smart pointers ALSO reference the DLL they came from. This would increase the client data size, but you wouldn't need to touch the DLL. You might even recycle the LoadLibrary/FreeLibrary reference counter, however that might hit performance.

此外,如果你得到循环DLL依赖,这些方案都不会帮助太多。 X引用DllB.Y,它引用DllA.Z)。我还没有一个很好的解决方案,不需要requrie全球知识。

Also, none of these schemes help much if you get circular DLL dependencies (Component DllA.X references DllB.Y, which references DllA.Z). I haven't yet fould a good solution to that that doesn#t requrie global knowledge.

这篇关于C ++:Dll卸载问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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