切换语言为:繁体

C++中的system()函数

  • 爱糖宝
  • 2024-10-12
  • 2036
  • 0
  • 0

C++中,system()函数是一个系统调用函数。函数的原型定义在stdlib.h/cstdlib头文件或者process.h头文件中。

process.h这个头文件并不是ISOC或者C++标准的一部分,而是基于某些操作系统和特定编译器的扩展,比如在Windows平台上的MSVC(Microsoft Visual C++)编译器。

该文件主要用来进行进程控制。可以分为以下八个主要方向:

① 进程控制

  • abort(): 强制终止当前进程,并产生一个SIGABRT信号。这通常会导致进程异常终止,并吐核。

  • exit(): 正常终止当前进程。

  • _exit(): 类似exit(),但是不调用任何清理处理程序,直接终止进程。常用在紧急情况下的快速退出。

② 获取进程信息

  • _getpid(): 获取当前进程的ID。

  • _getppid(): 获取当前进程的父进程ID。

③ 进程环境

  • getenv(const char *varname): 获取环境变量的值。如果环境变量不存在,则返回NULL。

  • putenv(const char *envstring): 设置或者删除环境变量。envstring的格式为varname=value,如果要删除一个环境变量,可以将value设置为空字符串。

④ 进程间通信(IPC)

  • process.h头文件本身不提供IPC的函数,但是与进程相关的IPC通常涉及到管道(pipes)、信号(signals)、共享内存(shared memory)等机制。这些功能会在其他的头文件中定义。

⑤ 线程属性

  • _beginthreadex(): 创建一个新线程。这是创建线程的低级函数,提供了更多的控制。

  • _endthreadex(): 终止一个由_beginthreadex()创建的线程。

⑥ 执行和替换进程映像

  • _exec* 系列函数:这些函数用于替换当前进程的映像。

⑦ 创建新进程

  • spawn* 系列函数:这些函数用于创建一个新的进程来执行一个程序。

⑧ 系统命令执行

  • system)const char *command): 执行一个命令行字符串。这个函数会创建一个子进程来执行命令,然后等待命令执行完成。

process.h头文件中,system()是这样定义的。

#ifndef _CRT_SYSTEM_DEFINED

#define _CRT_SYSTEM_DEFINED

 int __cdecl system(const char *_Command);

#endif

当不存在对于_CRT_SYSTEM_DEFINED的具体定义时,就定义该宏,并没有给他分配任何特定的值,并包含system函数的声明。

在上述代码段中,出现了__cdecl这个关键字。这个关键字是指定函数调用约定的关键字之一。 调用约定指的是:在C和C++中,调用约定定义了函数参数如何被传递到函数,以及函数返回时谁负责清理调用栈。不同的调用约定可以影响函数的调用方式和性能。

__cdecl调用约定规定了以下几个方面:

  1. 参数传递:参数从右到左被压入堆栈;

  2. 堆栈清理:调用者(调用函数的代码)负责清理堆栈上的参数;

  3. 名称修饰:在C语言中,函数名称可能会被修饰(添加下划线前缀),比如system可能被转换为_system

常见的调用约定还有:

  • __stdcall:在Windows API中广泛使用,参数从右到左被压入堆栈,但被调用者负责清理堆栈。

  • __fastcall:参数使用就差你其传递,以减少堆栈操作,提高性能。

  • thiscall:用于成员函数的调用,第一个参数是this指针,传递给函数的第一个参数之前。

最好不要尝试显式指定调用约定,它是编译器和平台特定的。 比如在GCC和Clang中,是使用__attribute__来指定调用约定:

#ifdef __GNUC__
__attribute__((cdecl)) void myFunction() {
    ;
}
#endif

在MSVC中,是直接使用调用约定关键字:

void __cdecl myFunction(){
	;
}

编译器的默认约定已经足够高效,只有在与比较旧的C代码库交互或者有特定的性能需求时,才可能需要考虑调用约定。

该函数会调用操作系统。首先system函数接收一个字符串,并将它作为要执行的命令传递给系统的命令行解释器。在Windows上通常是cmd.exe,而在linux上通常是/bin/sh。 此外,在调用时system()时,该操作会新建一个进程,因此会有一些性能上的问题。在执行完毕后,返回命令执行后的退出状态。在Unix-like系统中返回值通常是命令的退出码,在Windows系统中,如果成功执行,返回值通常是0。

0条评论

您的电子邮件等信息不会被公开,以下所有项均必填

OK! You can skip this field.