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

How to put arguments in a function at run time?

所以我在我的 C++ 程序中使用了 execlp。 execlp 的形式为“int execlp(const char *file, const char *arg0,...,const char *argn)”,这意味着它可以接受任意数量的参数。我只想知道有没有一种方法可以在 运行 时间将参数放入此函数中?由于参数是由用户提供的,我无法知道参数的确切数量。当然,我可以从一开始就选择一个大得离谱的数字,但这不会很 efficient.I 需要一种更有效的方法来允许我在 运行 时间提出论点。

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

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

The execv(), execvp(), and execvpe() functions provide an array of pointers to null-terminated strings that represent the argument list available to the new program. The first argument, by convention, should point to the filename associated with the file being executed. The array of pointers must be terminated by a NULL pointer.

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

你显然需要,如, to use functions like execv(3), which takes an array of arguments to execve(2) syscall. You could allocate that array in C dynamic memory with malloc(3)或朋友(calloc)。如果使用 C++ 编码,您将使用 new.

举个无用的例子,这里有一段代码在参数数组 12、.... nargs[ 上执行 /bin/echo =59=] 其中 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 没有 return。但是,在其他情况下(例如,如果在 execv 之前使用 fork,那么父进程将继续并稍后 waitpid),您需要一个循环来 free 每个单独的元素(strdup 的结果),那么你需要 free 整个 myargs 数组。

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

真正的C++11 you still need the array argument to execv to be an array of char*. You might consider using (as an intermediate step) some std::vector<std::string> but you'll need at least to transform it into a std::vector<char*> then pass the data to execve. Read about std::string (and its c_str member function) and 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 可能会失败,尤其是当参数数组太大时;通常限制是几十万个元素,但它可以小得多。