如何修复 MSVC 2005 错误:未解析的外部符号 __environ

Posted

技术标签:

【中文标题】如何修复 MSVC 2005 错误:未解析的外部符号 __environ【英文标题】:how can I fix the MSVC 2005 error: unresolved external symbol __environ 【发布时间】:2011-01-10 12:43:19 【问题描述】:

在我的应用程序中,我需要直接访问 _environ 变量,因为我必须有类似 glibc unsetenv 的东西(你不能通过 setenv 或 putenv 获得)。

这是我需要使用的代码:

//////////////////////
// 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 版本。 IE。这段代码:

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() 的文件。所以比以前多了一个错误。

【问题讨论】:

我在字里行间读到这里,但听起来像:您已经做了一些实验,并且您能够使用相同的编译和链接标志链接到 _wenviron 变量,但不能使用 _environ?跨度> 我刚刚尝试过:我将它重新编码为使用 _wenviron(这对我来说并不是真正的解决方案,而只是用于测试),但后来我得到了错误:未解析的外部符号 __wenviron 【参考方案1】:

我不确定我是否理解,getenv_s() 有什么问题?它是全局变量 __environ 的等效函数。它是多字节的,而不是 unicode,因此它应该可以在 VS 2005 编译器所针对的所有平台上正常工作。 “_s”表示“安全”,意味着该操作经过重新设计,以减少黑客通过缓冲区溢出等进行的利用。

【讨论】:

我必须使用上面的代码才能工作。该代码将覆盖 _environ 指向的内存。我不知道哪个 MSVC 函数可以做到这一点。 OP 正在尝试从全局共享的 libc 变量中删除环境变量。我不知道为 OP 执行该操作的库函数,它会很好,因为它可以以线程安全的方式执行。 抱歉,我现在看到了。据我所见,删除环境变量的唯一可靠方法是使用 Win32 函数 SetEnvironmentVariable 并为该值传递 NULL。此 API 仅在 Windows 2000 及更高版本上受支持。 如果我想让它在Win98及更高版本上运行,我该怎么办? 根据 VS 2008 文档,SetEnvironmentVariable 的要求是: 客户端:需要 Windows Vista、Windows XP、Windows 2000 Professional、Windows NT Workstation、Windows Me、Windows 98 或 Windows 95。MSDN 可能反映了对 Windows 98 的停止支持。

以上是关于如何修复 MSVC 2005 错误:未解析的外部符号 __environ的主要内容,如果未能解决你的问题,请参考以下文章

使用Boost.Python修复未解析的外部符号

由于 MySql 连接器 C++,如何修复未解析的外部符号?

只有 wWinMain MSVC 2019 的链接器错误无法解析外部符号

error LNK2019: 无法解析的外部符

MSVC 中的链接错误 LNK2019,带有 __imp__ 前缀的未解析符号,但应该来自静态库

带有 MSVC++ 的 exiflib