2010-03-18 35 views
4

有什么办法可以访问命令行参数,而不使用main参数?我需要在另一个功能中访问它,并且我不想让它通过。访问命令行参数,而不使用char ** argv主

我需要一个只能在Mac OS和Linux上使用GCC的解决方案。

+8

我坚信你应该通过他们。我认为依靠一个全球性的国家永远不是一件好事。 – zneak

+1

传递它们不一定非常复杂 - 你可以将它们处理成一个内部的args-and-options结构体,并且只传递一个单一的东西,避免任何重复的argc + argv循环/验证。 – Cascabel

+1

Jefromi的评论的一个例子可以在GNU的gengetopt工具的功能中看到。这个程序是要走的路,应该考虑这个工具。 – dmckee

回答

3

我不认为你应该这样做,因为C运行库将准备参数并通过int argc, char **argv将它传递到主文件中,不要试图通过黑客行为来操纵行为,因为它很可能是不可移植的或可能未定义的行为!坚持规则,你将有可移植性......除了打破它之外没有别的办法...

+0

正如问题所述,它不需要可移植,只需要与GCC一起工作(我只在平台特定的源文件中使用它)。 –

+0

想过之后,这将是最好的解决方案。 –

1

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

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

+1

这些似乎并没有在Mac OS上工作 –

2

如果你愿意,你可以将它们复制到全局变量中。

0

为什么传递一个指针指向已经被占用的空间的指针有那么一些原因?在消除相关功能的争论之后,您不会得到任何真正的节省,并且您可以引发一场有趣的焰火表演。通过创意hackery围绕main()的调用堆栈进行漫游通常会导致未定义的行为,或者依赖编译器的特定行为。两者对功能和便携性都不好。

请记住,有争议的参数是指针参数,无论你做什么,它们都将消耗空间。它们索引的便利性与sizeof(int)一样便宜,我没有看到任何不使用它的理由。

这听起来像是你正在进行过于积极和过早的优化,或者你不得不将功能添加到你真正不想混淆的代码中。在任何情况下,按照惯例做事都会节省时间和麻烦。

+0

我不想优化,我试图访问主外的命令行参数。 –

1

在Linux中,你可以打开/proc/self/cmdline(假设/proc存在)和手动解析(这仅要求如果需要的argc/argv的main() - 例如,在一个全球性的构造 - 否则最好是通过他们通过全球变数)。

更多的解决方案,可在这里:http://blog.linuxgamepublishing.com/2009/10/12/argv-and-argc-and-just-how-to-get-them/

是啊,这是毛和不可移植的,但如果你要解决实际问题,你可能不关心。

+0

这是要求它可以在Mac OS上工作 – Andras

6

我不知道如何在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变量可能不会尚未建成等...