C \ C ++中主函数的签名可以包含3个参数:
main( int argc, char *argv[ ], char *envp[ ] )
第三个是环境变量。
我正在VS10下编译一个库,因此我没有main()
。如何获得与char *envp[]
中完全相同类型的环境变量?我宁愿不使用.NET来减少依赖性,也许有一天可以开放便携性。
答案 0 :(得分:6)
GetEnvironmentStrings
返回一个(只读!)指针,指向进程的环境块的开头。
该块是一个连续的C风格字符串,包含以空值终止的key=value
对。该块以额外的空终止结束。
要使访问更方便,请使用以下功能:
typedef std::basic_string<TCHAR> tstring; // Generally convenient
typedef std::map<tstring, tstring> environment_t;
environment_t get_env() {
environment_t env;
auto free = [](LPTCH p) { FreeEnvironmentStrings(p); };
auto env_block = std::unique_ptr<TCHAR, decltype(free)>{
GetEnvironmentStrings(), free};
for (LPTCH i = env_block.get(); *i != T('\0'); ++i) {
tstring key;
tstring value;
for (; *i != T('='); ++i)
key += *i;
++i;
for (; *i != T('\0'); ++i)
value += *i;
env[key] = value;
}
return env;
}
当然,正确的实现会将其封装在一个类中,并且可能使用std::stringstream
而不是手动迭代字符,一次连接char
上的字符串。但我很懒。
用法是这样的:
environment_t env = get_env();
// Now you can write env[T("Var1")] to access a variable.
答案 1 :(得分:4)
我不知道windows,但在Linux上这个变量:
extern char **environ;
正是您所寻找的。 p>
#include <stdio.h>
#include <assert.h>
extern char **environ;
int main (int ac, char **av, char **envp) {
assert(envp == environ);
}
答案 2 :(得分:1)
以下内容基于@Konrad's excellent answer,主要有两点不同:
key
而不是value
。没有人应该在Windows中使用非宽字符。std::wstring str(buffer, buflen)
构建typedef std::map<std::wstring, std::wstring> environment_t;
environment_t get_env() {
environment_t env;
auto free = [](wchar_t* p) { FreeEnvironmentStrings(p); };
auto env_block = std::unique_ptr<wchar_t, decltype(free)>{
GetEnvironmentStringsW(), free};
for (const wchar_t* name = env_block.get(); *name != L'\0'; )
{
const wchar_t* equal = wcschr(name, L'=');
std::wstring key(name, equal - name);
const wchar_t* pValue = equal + 1;
std::wstring value(pValue);
env[key] = value;
name = pValue + value.length() + 1;
}
return env;
}
和{{1}}。我认为性能应该比使用char-by-char更好,尽管我还没有测量过它。代码:
{{1}}