2010-01-28 83 views
1

在我的应用程序中,我需要直接访问_environ变量,因为我必须拥有像glibc unsetenv(不能与setenv或putenv一样)的内容。我该如何修复MSVC 2005错误:无法解析的外部符号__environ

这是我需要使用代码:

////////////////////// 
// unsetenv for WIN32, taken from libc source 
int unsetenv(const char *name) 
{ 
    size_t len; 
    char **ep; 

    if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) 
    { 
     return -1; 
    } 

    len = strlen (name); 

    ep = _environ; 
    while (*ep != NULL) 
    if (!strncmp (*ep, name, len) && (*ep)[len] == '=') 
     { 
    /* Found it. Remove this pointer by moving later ones back. */ 
    char **dp = ep; 

    do 
     dp[0] = dp[1]; 
    while (*dp++); 
    /* Continue the loop in case NAME appears again. */ 
     } 
    else 
     ++ep; 

    return 0; 
} 

它一直很好,直到我们得到了一些问题,在某些系统中体现,所以我们试图使用运行时库的静态版本(/ MT旗)。现在

,我收到此错误:

unresolved external symbol __environ 

我读here和其他许多地方,这一变量已经过时和弃用。我想知道可能的解决方案。我也不能使用_wenviron变量,因为我们想要支持Windows 98.

在项目设置中,我明确地将它设置为使用MBCS(即不是Unicode)。我在这里有点失败。还有什么我必须设置?

只是为了测试,我也试过Unicode版本。即此代码:

int unsetenv(const wchar_t *name) 
{ 
    size_t len; 
    wchar_t **ep; 

    if (name == NULL || *name == '\0' || wcschr (name, '=') != NULL) 
    { 
     return -1; 
    } 

    len = wcslen (name); 

    ep = _wenviron; 
    while (*ep != NULL) 
    if (!wcsncmp (*ep, name, len) && (*ep)[len] == '=') 
     { 
    /* Found it. Remove this pointer by moving later ones back. */ 
    wchar_t **dp = ep; 

    do 
     dp[0] = dp[1]; 
    while (*dp++); 
    /* Continue the loop in case NAME appears again. */ 
     } 
    else 
     ++ep; 

    return 0; 
} 

我想知道为什么即使编译,因为我明确地将它设置为使用MBCS而不是Unicode。但也许这意味着别的东西。 (有人可以告诉我吗?)

不管怎么说,这会导致这些错误:

1>AuxLib.obj : error LNK2001: unresolved external symbol __wenviron 
1>ExtractInfo.obj : error LNK2001: unresolved external symbol __environ 

AuxLib.obj与此unsetenv文件()。所以比以前更多的错误。

+0

我正在阅读这里的行,但它听起来像:你做了一些实验,你能够使用相同的编译和链接标志链接到_wenviron变量,但不能使用_environ? – 2010-01-28 18:07:43

+0

我只是想:我重新编写它使用_wenviron(这不是一个真正的解决方案,但只是为了测试),但后来我得到了错误:无法解析的外部符号__wenviron – Albert 2010-01-28 18:20:12

回答

0

我不确定我明白,getenv_s()有什么问题?它是全局变量__environ的等效函数。它是多字节而不是unicode,所以它应该在VS 2005编译器的目标平台上正常工作。 “_s”的意思是“安全”,这意味着操作被重新设计,以减少黑客通过缓冲区溢出等利用。

+0

我必须上面的代码才能工作。该代码将覆盖_environ指向的内存。我不知道哪些MSVC功能可以做到这一点。 – Albert 2010-01-28 18:06:25

+0

OP正试图从全局共享的libc变量中删除一个环境变量。我不知道为OP执行该操作的库函数,它可以很好,因为它可以以线程安全的方式执行。 – 2010-01-28 18:08:31

+0

对不起,我现在看到了。从我所看到的,删除环境变量的唯一可靠方法是使用Win32函数SetEnvironmentVariable并为该值传递NULL。此API仅在Windows 2000及更高版本上受支持。 – 2010-01-28 18:21:57

相关问题