提升ini_parser - Singleton DLL问题

时间:2016-08-11 09:30:31

标签: c++ boost dll visual-studio-2008 visual-studio-2015

我有一个单例(这位于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 &section, 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的测试程序中重现此问题显然是不可能的。正确加载该值,程序继续执行。

是否有人遇到过这个问题,或者对此问题了解可能的解决方案/修复/解决方法?

1 个答案:

答案 0 :(得分:1)

除了评论中提到的@Richard Critten之外,单例和DLL并不容易混合在一起。它周围有很多陷阱,我的建议是避免使用带有DLL的单例。 (实际上,我认为单身人士在大多数情况下都是糟糕的设计,但这是另一回事。)

对于您的情况,您被迫按原样使用此代码,很可能应用程序“image”中的单例实例(每个已编译二进制文件的Microsoft术语,无论是EXE还是DLL)都未初始化,只有DLL中的单例实例。 (参见?你可以有超过1个单例实例。有道理,不是吗?)

要获得更准确的答案,我们必须查看sSingletonDefine的定义,并获取定义GetIniFile()的更多信息。

要进行调试,请查看s_IniObjectGetIniFile()的地址和thisGetValues()指针的地址。它们是一样的吗?