3

我想知道 C++ 如何实际将命令行参数转换为 char 数组?这是什么“秘密”代码?我在哪里可以查看执行此操作的代码(即使它在汇编中,我也知道一些汇编)?我正在使用 Linux,如果有帮助的话。

谢谢你

4

5 回答 5

7

在大多数(全部?)基于 Unix 的操作系统中,它们已经是一个数组。这就是操作系统在那里执行进程的方式——当一个进程启动时,已经有一组参数可供它使用。

将命令行转换为数组的代码位于 shell(如 bash)或启动另一个程序的任何其他程序中。bash它的资源是否可用,其他程序 - 它是不同的。

在 Windows 中,它们是一个字符串(您可以使用GetCommandLine()API 调用未修改),由 C 运行时库解析以将其转换为数组,因为语言规范要求它们以数组的形式出现。

对于使用 Visual C++ 编译的程序,执行此操作的代码包含在 Visual Studio 发行版中。您可能必须在安装程序中打开一个显示“包含 C 运行时库源”之类的复选框才能安装它。

于 2012-09-01T20:43:19.183 回答
2

管理命令行参数并在进程创建期间将其放入堆栈是一项操作系统工作。

对于 POSIX 系统,执行路径是:

  1. 在您的程序中,您调用 execle/execve/... 系统调用,将路径传递给新进程可执行文件和命令行参数。
  2. 这些数据进入内核
  3. 内核更新其内部结构以考虑新进程标识并为新进程分配地址空间(如果不再需要,内核也会清除旧地址空间)。内核用零初始化进程内存,将信息从旧内存复制到堆栈顶部的新地址空间。
  4. 内核将新进程放入调度队列并从exec()系统调用返回,将执行路径传输到用户空间并最终到达进程的入口点(这通常是crt0.o目标文件中的例程,默认情况下链接到每个可执行文件 -这个例程调用main())。

对于 Linux,您可以在此处查看此代码: http ://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/fs/exec.c#L383 :

383 /*
384  * 'copy_strings()' copies argument/environment strings from the old
385  * processes's memory to the new process's stack.  The call to get_user_pages()
386  * ensures the destination page is created and not swapped out.
387  */

do_execve()用户空间系统调用的内核对应部分中execve(),在第 1345 行,调用了copy_strings()'s,并且copy_strings()例程实际上完成了您所询问的工作。

于 2012-09-01T21:31:44.703 回答
2

这通常由操作系统在为程序创建进程时处理。这段代码很可能用 C 语言编写(例如,如果操作系统是用 C 语言编写的),也可以是汇编语言。要找到此代码,您可能必须查看操作系统代码。

希望这可以帮助!

于 2012-09-01T20:38:25.663 回答
1

它是 c 运行时库的一部分。如果您想知道那是什么,请看这里:什么是 C 运行时库?

我刚刚使用 Microsoft Visual Studio 创建了一个基本的 C++ 控制台应用程序,并在程序的第一行设置了一个断点。调试时,程序在该行停止,您调用查找调用堆栈以查看调用“main”的函数。调用函数是 c 运行时的一部分,它似乎包含一些操作命令行的代码……我没有仔细看,但这可能是你应该开始的地方。

于 2012-09-01T20:37:31.197 回答
1

有时它不是main()首先执行的实际。例如,在 Visual Studio 上mainCRTStartup(),作为入口点的函数调用 Windows API 来检索和解析命令行(如果使用调试器,您可以看到这一点)。

于 2012-09-01T20:38:39.510 回答