导出对象后何时释放 dll

Posted

技术标签:

【中文标题】导出对象后何时释放 dll【英文标题】:When to free a dll after exporting object 【发布时间】:2015-05-13 05:48:08 【问题描述】:

我正在通过以下方式从 dll 中导出函数:

extern "C" __declspec(dllexport) carsim::ICar* __cdecl createCarPlugin() 
     return new CarPlugin();

在我的主程序中,我显式加载了 dll 以提取此方法。接口 ICar 的声明被 dll 和主程序识别:

std::shared_ptr<ICar> PluginFactory::loadCarPlugin(const std::string& sCar) 
HINSTANCE oDllHandle = ::LoadLibrary(TEXT(sCar.c_str()));
if (!oDllHandle) 
    throw std::string("Could not LoadLibrary: "+sCar);


ICarFactory vFactoryFunc = reinterpret_cast<ICarFactory>(::GetProcAddress(oDllHandle, "createCarPlugin"));
if (!vFactoryFunc) 
    ::FreeLibrary(oDllHandle);
    throw std::string("Could not GetProcAddress: createCarPlugin");


std::shared_ptr<ICar> pResult(vFactoryFunc());

//::FreeLibrary(oDllHandle);

return pResult;

代码运行良好,除了一个问题:正如您所见,FreeLibrary 函数已被注释掉。那是因为我不确定何时必须释放图书馆。 ICar-Object 被放入一个共享指针中,因此它会(希望)在程序完成时被销毁。但是当我尝试在代码中释放库时,程序无法运行。

我必须在程序停止之前释放它吗?

任何帮助将不胜感激:)

【问题讨论】:

如果GetProcAddress 失败,你会在调用FreeLibrary 之前抛出,所以在这种情况下永远不会调用FreeLibrary 至于什么时候调用FreeLibrary,否则等你不再需要DLL的时候再调用。但是,请考虑为 DLL 中的每个函数调用调用 LoadLibrary/FreeLibrary 会增加一些开销,如果您需要调用多个函数,您可能希望在程序的早期加载一次 DLL,然后卸载一次您确定不会再调用 DLL 中的任何函数。 @joachim 谢谢,刚刚修好了 :) @joachim 我的库中只有一种方法可以导出 ICar-Object。导出对象后我真的不需要dll,我只需要使用对象本身 那打FreeLibrary那里就好了。 【参考方案1】:

只要您使用 DLL,它就需要保持加载状态,这包括使用 ICar 实例。如果您释放该库,然后在该 ICar 上调用一个函数,则该函数可能不再存在 - 您已经释放了它。

说“导出对象后我真的不需要 dll”是不正确的 - DLL 是该对象的代码所在的位置。

如果您希望 DLL 在程序的整个生命周期内保持加载状态,则无需显式释放它 - 进程退出时会自动清理它。

【讨论】:

好的,所以我可以让我的代码保持原样 - 没有 FreeLibrary() - 它会工作吗? :O 不错 :D ty

以上是关于导出对象后何时释放 dll的主要内容,如果未能解决你的问题,请参考以下文章

何时释放带有“自动释放”的对象?

自动释放的对象何时真正释放?

何时释放 AudioRecord 对象?

自动释放对象递减的保留计数何时减少?

线程同步 - 线程何时释放对象上的锁

何时释放/保留传递给辅助线程的对象?