Я разрабатываю UTF-8 API, который должен прозрачно работать независимо от ОС.
Для этого я заменяю getenv
на GetEnvironmentVariableW
, а char** env
передается main
по GetEnvironmentStringsW
.
Чтобы убедиться, что все правильно, я перебираю массив env
и проверяю каждое значение на GetEnvironmentVariableW
, чтобы убедиться, что они совпадают.
Это работает везде, но с MinGW / MSYS, где происходит сбой для переменной env temp
, где getenv = C:\msys64\tmp
и GetEnvironmentStringsW
возвращает C:\Users\appveyor\AppData\Local\Temp\1
Я проверил значение, используя c:\msys64\usr\bin\env MSYSTEM=MINGW32 c:\msys64\usr\bin\bash -l -c "echo $temp"
(аналогично тому, как выполняется сборка / тест) и там он возвращает C:\Users\appveyor\AppData\Local\Temp\1
.
Так что, похоже, GetEnvironmentVariableW
возвращает другое / неправильное значение.
Как это возможно? Можно ли этого избежать?
Код теста:
for(char** e = env; *e != 0; e++)
{
const char* key_begin = *e;
const char* key_end = strchr(key_begin, '=');
std::string key = std::string(key_begin, key_end);
std::string value = key_end + 1;
const char* env_value = boost::nowide::getenv(key.c_str());
TEST_EQ(env_value, value);
}
, где функция getenv (сокращена без проверки ошибок и т. Д. c):
char* getenv(const char* key)
{
static const size_t buf_size = 64;
wchar_t buf[buf_size];
GetEnvironmentVariableW(widen(key), buf, buf_size);
return narrow(buf);
}
Редактировать: мне удалось воспроизвести это с помощью следующего минимального кода:
#include <iostream>
#include <windows.h>
#include <string>
int main()
{
const size_t buf_size = 4000;
char buf[buf_size];
GetEnvironmentVariable("temp", buf, buf_size);
std::cout << buf << std::endl;
return 0;
}
При компиляции (например, в MSV C) и запускать с temp=Foobar ./a.out
, например, Git bash on Windows печатает C:\Users\alex\AppData\Local\Temp
, а не Foobar
. В GetEnvironmentStrings значение является правильным