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

Viewed 43

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 Answers
Related