(Это не такая большая проблема, как упражнение в педантичности, так что здесь.)
Я сделал хорошую маленькую программу, которая встроена в мою ОС Linux, но я думаю, что этодостаточно полезно, чтобы существовать на моей машине с Windows тоже.Таким образом, я хотел бы получить доступ к переменным среды Windows, и MSDN приводит пример, подобный этому:
const DWORD buff_size = 50;
LPTSTR buff = new TCHAR[buff_size];
const DWORD var_size = GetEnvironmentVariable("HOME",buff,buff_size);
if (var_size==0) { /* fine, some failure or no HOME */ }
else if (var_size>buff_size) {
// OK, so 50 isn't big enough.
if (buff) delete [] buff;
buff = new TCHAR[var_size];
const DWORD new_size = GetEnvironmentVariable("HOME",buff,var_size);
if (new_size==0 || new_size>var_size) { /* *Sigh* */ }
else { /* great, we're done */ }
}
else { /* in one go! */ }
Это не так хорошо (для меня), как использование getenv и просто проверка на нулевой указатель,Я также предпочел бы не распределять память динамически, так как я просто пытаюсь заставить программу работать как в Windows, так и в моей ОС Linux, что означает, что этот код MS должен хорошо играть с кодом nix.Более конкретно:
template <class T> // let the compiler sort out between char* and TCHAR*
inline bool get_home(T& val) { // return true if OK, false otherwise
#if defined (__linux) || (__unix)
val = getenv("HOME");
if (val) return true;
else return false;
#elif defined (WINDOWS) || defined (_WIN32) || defined (WIN32)
// something like the MS Code above
#else
// probably I'll just return false here.
#endif
}
Итак, мне нужно было бы выделить в куче универсально или сделать #ifdef
в вызывающих функциях, чтобы освободить память.Не очень красиво.
Конечно, я мог бы просто разместить 'buff' в стеке, но тогда мне пришлось бы создать новый TCHAR[]
, если 'buff_size' был недостаточно большим.на мой первый вызов GetEnvironmentVariable.Лучше, но что, если бы я был педантом и не хотел создавать лишние массивы?Есть какие-нибудь идеи по поводу чего-то более эстетически привлекательного?
Я не настолько осведомлен, так что кто-нибудь может завидовать мне намеренно, заставляя GetEnvironmentVariable потерпеть неудачу, чтобы получить размер строки?Кто-нибудь видит проблему с:
const DWORD buff_size = GetEnvironmentVariable("HOME",0,0);
TCHAR buff[buff_size];
const DWORD ret = GetEnvironmentVariable("HOME",buff,buff_size);
// ...
Любые другие идеи или предложения?(Или исправления к вопиющим ошибкам?)
ОБНОВЛЕНИЕ: много полезной информации ниже.Я думаю, что лучшим вариантом для того, что я пытаюсь сделать, является использование static char[]
типа:
inline const char* get_home(void) { // inline not required, but what the hell.
#if defined (__linux) || (__unix)
return getenv("HOME");
#elif defined (WINDOWS) || defined (WIN32) || defined (_WIN32)
static char buff[MAX_PATH];
const DWORD ret = GetEnvironmentVariableA("USERPROFILE",buff,MAX_PATH);
if (ret==0 || ret>MAX_PATH)
return 0;
else
return buff;
#else
return 0;
#endif
}
Возможно, это не самый элегантный способ сделать это, но это, вероятно, самый простой способ синхронизациидо того, что я хочу сделать между * nix и Windows.(Я также буду беспокоиться о поддержке Unicode позже.)
Спасибо за помощь, ребята.