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