在C ++11/14中实现一个单例时,我遇到了一个OOP概念上的限制,它缓存了一组从第三方DLL创建的shared_ptr
示例(设计糟糕的外部约束)。
//DLL1 data source session (third library)
class SessionFactory final
{
public:
static std::shared_ptr<ISession> CreateSession(const std::string& pi_dataSourceId);
};
//DLL2 client
class SessionCache final
{
public:
static SessionCache& Get()
{
static SessionCache s_instance;
return s_instance;
}
void clean() {m_sessions.clear();}
std::shared_ptr<ISession> getSession(const std::string& pi_dataSourceId)
{
auto im = m_sessions.find(pi_dataSourceId);
if (im == m_sessions.end())
{
auto l_session = SessionFactory::CreateSession(pi_dataSourceId);
m_sessions.insert(pi_dataSourceId, l_session)
return l_session;
}
else return im->second;
}
private:
std::map<std::string, std::shared_ptr<ISession>> m_sessions;
};
//optional explicit singleton content cleaning
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_DETACH:
SessionCache::Get().clean(); //=> runtime error R6025 pure virtual function call (cached ISession are no more referenced and their virtual dtor are called leading to runtime error R6025)
break;
}
return TRUE;
}
当我想在卸载客户端DLL时清除缓存(显式地从DllMain
过程或隐式地通过调用的静态示例析构函数),不幸的是,我遇到了"运行时错误R6025纯虚函数调用"系统异常,因为在卸载DLL2时DLL1已经被卸载。
由于ISession
的析构函数实现属于DLL1,因此在此步骤中无法访问它。
一个策略性的解决方案是将"静态"单元素分配修改为动态分配,但不再调用缓存的ISession
析构函数。
1.有人知道我该如何优雅地解决这个技术问题吗?
1.有人在Unix类系统中遇到过类似的技术限制吗?
1条答案
按热度按时间lnlaulya1#
不幸的是,我遇到了“runtime error R6025 pure virtual function call”系统异常,因为在DLL 2卸载时DLL 1已经被卸载了。
然后,您需要确保在DLL 2使用完DLL 1之前,DLL 1不能被卸载,方法是使DLL 1成为DLL 2的静态依赖项,或者让DLL 2在运行时通过
LoadLibrary()
/FreeLibrary()
手动递增/递减DLL 1的引用计数:系统在所有加载的模块上维护每个进程的引用计数。**调用LoadLibrary会增加引用计数。调用FreeLibrary或FreeLibraryAndExitThread函数会减少引用计数。**当模块的引用计数达到零或进程终止时,系统会卸载模块(无论引用计数如何)。
或者: