c++ - Boost ini_parser - 单例 DLL 问题

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

我有一个单例(它位于一个 VS2008 DLL/Lib 中,它与 VS2015 项目中的 header 一起使用)

UtilIniFile &UtilIniFile::GetIniFile()
{
    static UtilIniFile s_IniObject;
    if (/*check if file has been loaded*/)
    {
        s_IniObject.Load(s_IniObject.m_fullfile);
    }
    return s_IniObject;
}

调用加载函数并正确解析 ini 文件,没有错误/异常。

//boost::property_tree::ptree m_PropTree;
boost::property_tree::ini_parser::read_ini(CT2A(filename).m_szBuffer, m_PropTree);

值是,虽然存在写函数,但没有写入 ptree/文件,从 ptree 中读取没有任何问题 - 没有异常(exception)。

获取函数如下所示:

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 函数与代码中的所有其他 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 . GetValue 时不会发生这种情况。从 DLL 中调用函数,例如MFC 类中的某处是一个调用的函数,它进入 DLL 并从 ini 文件/ptree 加载一些东西。尝试直接从 VS'15 项目加载值会导致一些“奇怪”的行为。

即使添加 Load调用GetValue模板,就在 ptree.get 之前被称为,在Load里面函数 m_children ptree 的成员有一个有效的地址并返回 GetValue模板地址再次无效。当然它然后崩溃this was 0xF. .未卸载 DLL。

在不使用 DLL 的测试程序中重现此问题显然是不可能的。该值被正确加载,程序继续执行。

有没有人遇到类似的问题,或者知道此问题的可能解决方案/修复/解决方法?

最佳答案

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

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

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

为了调试,查看GetIniFile()s_IniObject的地址和GetValues()中this指针的地址。它们是一样的吗?

关于c++ - Boost ini_parser - 单例 DLL 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38892457/

相关文章:

c++ - 如何在调试和重新分发期间包含 DLL?

c++ - 线程中 TCP 套接字的奇怪行为

c++ - boost::variate_generator 语法错误

c++ - 创建和修改系统路径变量

c++ - 如何将结构从 C++ 应用程序传递到 C++ Win32 DLL?

c++ - 如何动态地为 Vector<Point> 分配内存?

c++ - For 循环不按公式输出正确的结果

c++ - 带有boost的变量参数列表?

c++ - 如何在 Ubuntu 14.04 的 C++ 程序中使用 graphViz 库?

c++ - 具有适配 std::pair 点类型的 R-Tree 查询