如何在运行时将参数放入函数中?

所以我在我的c ++程序中使用execlp。 execlp的forms是“int execlp(const char * file,const char * arg0,…,const char * argn)”,这意味着它可以采用任意数量的参数。 我只是想知道,有什么办法可以在运行时将这个函数放在这个函数里面? 由于参数是由用户提供的,因此我无法知道参数的确切数量。 当然,我可以从一开始就挑出一大堆可笑的数字,但这样做效率不高。我需要一个更有效的方法来让我在运行时提出争论。

如果您不需要使用execlpexecvexecvp是您的要求更好的功能。

http://linux.die.net/man/3/execlp

execv()execvp()execvpe()函数提供了一个指向null结尾字符串的指针数组,这些字符串表示新程序可用的参数列表。 按照惯例,第一个参数应指向与正在执行的文件相关的文件名。 指针数组必须以NULL指针终止。

我猜你正在使用Linux或其他POSIX系统。

正如R.Sahu回答的那样 ,你显然需要使用像execv(3)这样的函数, execv (2)系统调用接收一个参数数组 。 您可以使用malloc(3)或朋友( calloc )在C动态内存中分配该数组。 如果使用C ++进行编码,则可以使用new

对于一个无用的例子,这里是一个代码块执行/bin/echo在参数2 ,…. nargs其中int nargs; 是严格肯定的。

C99中的变体

 assert(nargs>0); char** myargs = malloc ((nargs+2)*sizeof(char*)); if (!myargs) { perror("malloc myargs"); exit(EXIT_FAILURE); }; myargs[0] = "echo"; for (int ix=0; ix<nargs; ix++) { char buf[32]; snprintf(buf,sizeof(buf),"%d",ix); myargs[ix+1] = strdup(buf); if (!myargs[ix+1]) { perror("strdup"); exit(EXIT_FAILURE); }; } myargs[nargs+1] = NULL; execv("/bin/echo", myargs); perror("exec echo failed"); exit(EXIT_FAILURE); 

在C + +中,你会例如代码char**myargs = new char*[nargs+2] ;

一般来说,你需要以后free (在C ++中使用delete )堆分配的内存。 这里并不是真的需要,因为execv不会返回。 然而,在其他情况下(例如,如果在execv之前使用fork ,所以父进程将继续,并稍后waitpid ),您需要一个循环来free每个单独的元素( strdup结果),然后您需要free整个myargs数组。

关于调用任意签名的任意(运行时已知)函数的一般问题,在普通标准C99中这是不可能的,但是您可以使用一些库(包含几个汇编程序或机器特定的代码),比如libffi

在真正的C ++ 11中 ,仍然需要execv的数组参数为char*的数组。 你可能会考虑使用(作为一个中间步骤)一些std::vector<std::string>但是至少需要把它转换成std::vector<char*>然后把数据传递给execve 。 阅读关于std :: string (及其c_str成员函数)和std :: vector (及其data成员函数)。 你可以尝试像这样:

  assert (nargs>0); std::vector<std::string> vecstr; vecstr.resize(nargs+2); vecstr[0] = "echo"; for (int ix=0; ix<nargs; ix++) vecstr[ix+1] = std::to_string(ix+1); std::vector<const char*> vecargs; vecargs.resize(nargs+2,nullptr); std::transform(vecstr.begin(), vecargs.begin(), [](const std::string&s) { return s.c_str(); }); vecargs[nargs+1] = nullptr; execv("/bin/echo", vecargs.data()); throw std::runtime_error(std::string{"exec failure:"}+strerror(errno)); 

请注意, execv可能会失败,特别是当参数数组太大时; 通常这个极限是几十万个元素,但是可以小得多。