(这与其说是一个问题,不如说是一种迂腐的做法,所以就这样吧。)
我已经制作了一个很好的小程序,它是我的 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[]
如果我第一次调用 GetEnvironmentVariable 时“buff_size”不够大。更好,但是如果我是一个学究并且不想到处创建多余的数组怎么办?关于更美观的东西有什么想法吗?
我知识不多,所以有人会嫉妒我故意强迫 GetEnvironmentVariable 失败以获得字符串大小吗?有没有人看到以下问题:
const DWORD buff_size = GetEnvironmentVariable("HOME",0,0);
TCHAR buff[buff_size];
const DWORD ret = GetEnvironmentVariable("HOME",buff,buff_size);
// ...
还有其他想法或建议吗? (或者纠正明显的错误?)
更新:
下面有很多有用的信息。我认为我想做的最好的选择是使用static char[]
like:
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 支持。)
感谢所有提供过帮助的人。