11

有什么方法可以访问命令行参数,而不使用 main 的参数?我需要在另一个函数中访问它,我不希望将它传入。

我需要一个只能在带有 GCC 的 Mac OS 和 Linux 上运行的解决方案。

4

6 回答 6

13

我不知道如何在 MacOS 上做到这一点,但我怀疑我将在这里描述的技巧可以通过一些交叉阅读移植到 MacOS。

在 Linux 上,您可以使用 ELF 二进制文件中所谓的“.init_array”部分来注册在程序初始化期间(在调用 main() 之前)调用的函数。此函数与普通 main() 函数具有相同的签名,除了它返回“void”。因此,您可以使用此函数来记住或处理 argc、argv[] 和 evp[]。

这是您可以使用的一些代码:

static void my_cool_main(int argc, char* argv[], char* envp[])
{
    // your code goes here
}

__attribute__((section(".init_array"))) void (* p_my_cool_main)(int,char*[],char*[]) = &my_cool_main;

PS:此代码也可以放在库中,因此它应该适合您的情况。它甚至可以工作,当您的 prgram 与 valgrind 一起运行时 - valgrind 不会派生新进程,这会导致 /proc/self/cmdline 显示原始的 valgrind 命令行。

PPS:请记住,在这个非常早期的程序执行期间,许多子系统还没有完全初始化——我尝试了 libc I/O 例程,它们似乎可以工作,但不要依赖它——甚至可能还没有构建 gloval 变量, ETC...

于 2014-07-13T00:38:03.483 回答
4

在 Linux 中,您可以打开/proc/self/cmdline(假设/proc存在)并手动解析(仅当您之前需要 argc/argv 时才需要- main()例如在全局构造函数中 - 否则最好通过全局变量传递它们)。

此处提供更多解决方案:http: //blog.linuxgamepublishing.com/2009/10/12/argv-and-argc-and-just-how-to-get-them/

是的,它很粗俗且不可移植,但如果你正在解决实际问题,你可能不在乎。

于 2014-01-21T19:12:36.743 回答
3

如果需要,您可以将它们复制到全局变量中。

于 2010-03-18T16:39:55.477 回答
2

我认为你不应该这样做,因为 C 运行时会准备参数并将其传递给 main via int argc, char **argv,不要试图通过破解它来操纵行为,因为它在很大程度上是不可移植或可能未定义的行为!遵守规则,您将拥有可移植性......除了打破它之外别无他法......

于 2010-03-18T16:37:53.403 回答
1

你可以。大多数平台提供全局变量 __argc 和 __argv。但是,我再次支持 zneak 的评论。

PS 使用 boost::program_options 来解析它们。请不要在 C++ 中以任何其他方式执行此操作。

于 2010-03-18T16:32:06.337 回答
0

为什么将指针传递到已经消耗的空间是如此糟糕?您不会因为消除有关函数的参数而获得任何真正的节省,并且您可以引发有趣的烟花表演。用创造性的技巧绕过 main() 的调用堆栈通常会导致未定义的行为,或者依赖于编译器特定的行为。两者都分别对功能和便携性不利。

请记住,所讨论的参数是指向参数的指针,无论您做什么,它们都会占用空间。它们索引的便利性与 sizeof(int) 一样便宜,我看不出有任何理由不使用它。

听起来您正在积极且过早地进行优化,或者您不得不将功能添加到您真的不想弄乱的代码中。在任何一种情况下,按常规做事都会节省时间和麻烦。

于 2010-03-19T02:30:32.110 回答