我有一个单例(这位于VS2008 DLL / Lib中,与VS2015项目中的标题一起使用)
UtilIniFile &UtilIniFile::GetIniFile()
{
static UtilIniFile s_IniObject;
if (/*check if file has been loaded*/)
{
s_IniObject.Load(s_IniObject.m_fullfile);
}
return s_IniObject;
}
调用load函数并正确解析ini文件,没有错误/异常。
//boost::property_tree::ptree m_PropTree;
boost::property_tree::ini_parser::read_ini(CT2A(filename).m_szBuffer, m_PropTree);
值是,虽然存在写入函数,但是没有写入ptree /文件,从ptree读取没有任何问题 - 没有例外。
get函数如下所示:
template <class TValue>
bool GetValue(const std::string §ion, const std::string &key, TValue &value, const TValue &defaultValue = TValue())
{
try
{
value = m_PropTree.get<TValue>(section + '.' + key, defaultValue);
}
catch (const boost::property_tree::ptree_error &)
{
return false;
}
return true; //All fine
}
get函数是IMO,正确调用代码中的所有其他get函数。
std::string str;
sSingletonDefine.GetValue<std::string>("SECTION", "Key", str, "defValue");
当调试到singleton-getter GetIniFile
并检查它的值时,一切看起来都很好,单例内的ptree在成员m_children
上有一个正确的地址。从函数和调试返回到模板GetValue<std::string>(...)
,ptree显示m_children = 0x0000000f
。当从DLL内调用GetValue
函数时,例如,这不会发生。 MFC类中的某个地方是一个被调用的函数,它进入DLL并在那里从ini文件/ ptree加载一些东西。试图直接从VS&#15; 15项目加载一个值导致一些&#34;奇怪的&#34;行为。
即使在调用Load
之前的GetValue
模板中添加ptree.get
来电,也可以在ptree的Load
函数m_children
成员内有一个有效的地址,并返回GetValue
模板,地址再次无效。当然它会崩溃this was 0xF.
。 DLL没有被卸载。
在不使用DLL的测试程序中重现此问题显然是不可能的。正确加载该值,程序继续执行。
是否有人遇到过这个问题,或者对此问题了解可能的解决方案/修复/解决方法?
答案 0 :(得分:1)
除了评论中提到的@Richard Critten之外,单例和DLL并不容易混合在一起。它周围有很多陷阱,我的建议是避免使用带有DLL的单例。 (实际上,我认为单身人士在大多数情况下都是糟糕的设计,但这是另一回事。)
对于您的情况,您被迫按原样使用此代码,很可能应用程序“image”中的单例实例(每个已编译二进制文件的Microsoft术语,无论是EXE还是DLL)都未初始化,只有DLL中的单例实例。 (参见?你可以有超过1个单例实例。有道理,不是吗?)
要获得更准确的答案,我们必须查看sSingletonDefine
的定义,并获取定义GetIniFile()
的更多信息。
要进行调试,请查看s_IniObject
中GetIniFile()
的地址和this
中GetValues()
指针的地址。它们是一样的吗?