【问题标题】:How can I avoid this error with setenv in C?如何在 C 中使用 setenv 避免此错误?
【发布时间】:2018-10-05 14:56:39
【问题描述】:

第一次披露:我不是一个 C 程序员。我正在尝试编译一组具有很多血统的 C 和 Fortran 代码,使用 Makefile 生成用于工程计算的可执行文件。我在 sgi Irix (6.5.30) 上使用 gcc 4.7.1。在编译主程序期间,首先我收到关于“函数‘setenv’的隐式声明”的警告。随后,在生成所有目标 'o' 文件后,编译以错误结束:

ld32:错误 33:未解析的数据符号“setenv”

注释掉定义“setenv”的单行允许编译成功并生成可执行文件。然而,setenv 的行对程序来说是至关重要的。

这导致我写了一个测试代码并确认了同样的问题:

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
int main()
{
   setenv("FILE","/usr/bin/example.c",50);
   printf("File = %s\n", getenv("FILE"));
   return 0;
}

根据我在堆栈交换和其他网站上谷歌搜索时发现的所有建议,我尝试包含不同的标题,例如

#define _POSIX_C_SOURCE

#define _GNU_SOURCE

在任何#define 语句之前。我还尝试使用-std=c99 以及-D_XOPEN_SOURCE-D_GNU_SOURCE 进行编译,但没有成功。

我也尝试过使用 Irix 的原生 C 编译器(cc 和 c99)编译测试程序,我得到了同样的错误:

未解析的文本符号“setenv”

有人可以帮我看看我应该在我的系统和/或环境变量中寻找什么来解决这个错误吗?

【问题讨论】:

  • 相关:在 iOS 上我遇到了同样的问题:putenv 未找到。
  • @Jean-FrançoisFabre:那是因为 iOS 基于 BSD。 BSD 函数是setenvputenv 是 SVR4 的等价物。这是历史性的。
  • 啊,也可能是一个有趣的问答:)

标签: c gcc posix irix


【解决方案1】:

看起来 IRIX libc 确实不支持setenv() 命令。您将不得不像这样使用putenv() 重写它:

putenv("FILE=/usr/bin/example.c");

另请参阅IRIX putenv() manpage。寻找setenv() 没有显示任何命中,所以我假设,这个函数丢失了(注意:IRIX 6.5.30 是从 2006 年开始的)

【讨论】:

  • 顺便说一句。我为setenv() 找到了this source code。可能实现起来比改代码容易
  • @IngoLeonhardt 特别是如果你真的需要overwrite 标志,这是一个不错的选择!
  • 好的,谢谢。我看到了 setenv() 的源代码。那么我现在需要做什么呢?将该源代码放在一个单独的文件中并与主文件一起编译或将其添加到主文件的末尾?我需要声明或原型吗?对不起我的无知。
  • @KaushikMallick 如果您确实不需要需要overflow 参数(它确实很少有用),只需使用 putenv。否则,您可以 c&p 的 setenv 代码并将其放在您的 main 函数之前,应该这样做。
  • 不错不错。可以做。我想要工作的原始代码是: setenv("CCX_JOBNAME_GETJOBNAME",jobnamec,1);如何用 putenv() 替换它。再次非常感谢。
【解决方案2】:

过去,设置或更改环境变量一直存在问题。对于环境块有一个固定的内存区域,已经使用了各种解决方案。这些包括链接内存片段和使用realloc(3)。改变环境块一直没有标准的方法,现在C99明确排除了putenv(3),也没有提到setenv(3)。

POSIX 包括 setenv(3)putenv(3),它们的工作类似。但是,该标准确实声明 setenv(3) 是首选函数:

“对于是否需要 System V putenv() 函数或 BSD setenv() 函数作为强制函数存在相当大的争论。选择 setenv() 函数是因为它允许实现unsetenv() 函数删除环境变量,无需指定额外的接口。putenv() 函数可作为 XSI 扩展使用。"

两者都不是线程安全的。

This 可能是重复的,尽管它特别提到了 C99 而不是 gcc

【讨论】:

    【解决方案3】:

    谢谢大家,我的问题解决了! 我换了

    setenv("CCX_JOBNAME_GETJOBNAME",jobnamec,1)
    

    在我原来的主 C 程序中 与

    putenv("CCX_JOBNAME_GETJOBNAME=jobnamec")
    

    我能够编译代码完成以创建最终的可执行文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-02
      • 2023-04-02
      • 2022-01-25
      • 1970-01-01
      相关资源
      最近更新 更多