Boost ini_parser - Singleton DLL issue

0

I have a singleton (this lies in a VS2008 DLL/Lib which is being used with the header in a VS2015 project)

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

the load function is called and the ini file is properly parsed without errors/exceptions.

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

Values are, there is no write to the ptree/file though a write function exists, read from the ptree without any problem - no exceptions.

The get function looks like this:

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
}

The get function is, IMO, correctly called as all other get functions in the code.

std::string str;
sSingletonDefine.GetValue<std::string>("SECTION", "Key", str, "defValue");

When debugging into the singleton-getter GetIniFile and inspecting its values, all looks fine, the ptree inside of the singleton has a proper address on the member m_children. Returning from the function and debugging into the template GetValue<std::string>(...) the ptree shows m_children = 0x0000000f. This does not happen when the GetValue function is called from within the DLL, e.g. somewhere in a MFC class is a function called, which goes into the DLL and there it loads something from the ini file/ptree. Trying to load a value directly from the VS'15 project results in some "strange" behaviour.

Even when adding a Load call in the GetValue template, right before the ptree.get is called, inside of the Load function m_children member of ptree has a valid address and back in the GetValue template the address is invalid again. Of course it then crashes this was 0xF.. The DLL is not being unloaded.

Reproducing this problem, in a test program not using a DLL, is apparently not possible. The value is correctly loaded and the program continues to execute.

Has anyone experienced a smilar problem, or know a possible solution/fix/workaround for this issue ?

c++
boost
dll
visual-studio-2008
visual-studio-2015
asked on Stack Overflow Aug 11, 2016 by Blacktempel

1 Answer

1

Besides what @Richard Critten mentioned in the comment, singleton and DLL aren't blended together easily. There are a lot of pitfalls around it and my recommendation is to avoid using singletons with DLLs together. (Actually, I think singletons are bad design anyway in most cases, but this is a different story.)

For your case, where you are forced to use this code as is, it's very likely that the singleton instance in your application "image" (Microsoft term for each compiled binary, whether it's EXE or DLL), isn't initialized, only the singleton instance in the DLL. (See? You can have more than 1 singleton instance. Makes sense, isn't it?)

For more accurate answer we have to see the definition of sSingletonDefine and get more information where GetIniFile() is defined.

For debugging, look at the address of s_IniObject in GetIniFile() and the address of this pointer in GetValues(). Are they the same?

answered on Stack Overflow Aug 11, 2016 by Yehezkel B.

User contributions licensed under CC BY-SA 3.0