utf8 locale in boost::filesystem::path::imbue in DLL crashes application after unloading dll

141 Views Asked by At

Every char string in our codebase is utf8. In order to properly convert these to utf16 strings within boost::filesystem::path a suitable locale is imbued. We're delivering a DLL for third party use. This works fine, until someone uses the same boost::filesystem::path in the calling program.

After unloading the DLL the global locale seems to be corrupted and causes the program to crash.

shared library code:

#include <boost/filesystem/path.hpp>
#include <codecvt>
#include <iostream>

extern "C" __declspec(dllexport) void thefunction()
{
    boost::filesystem::path::imbue(std::locale(std::locale(), new std::codecvt_utf8_utf16<wchar_t>()));

    boost::filesystem::path path = "a path in the dll";
    std::wcout << path.wstring() << "\n";
}

executable code:

#include <boost/filesystem/path.hpp>
#include <iostream>
#include <Windows.h>

int wmain(int argc, wchar_t* argv[])
{
    auto handle = LoadLibraryEx(L"thedll.dll", NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
    auto thefunction = (void(*)())GetProcAddress((HMODULE)handle, "thefunction");
    thefunction();

    FreeLibrary(handle);

    boost::filesystem::path path = "a path in the exe"; // <--- CRASH!
    std::cout << path.string() << "\n";
}

Is there a proper way to imbue a locale within a DLL, so that it remains valid after unloading it?


A few remarks:

  • tested with boost 1.55 MSVC2010
  • in production code the imbue call is within the DLLMain DLL_PROCESS_ATTACH
  • i have tried to re-imbue the previous locale on DLL_PROCESS_DETACH (from a stored global variable), but this seems to result in problems with cascaded DLL loadings (all of which use the same mechanism again)
  • the LOAD_WITH_ALTERED_SEARCH_PATH is required
0

There are 0 best solutions below