Convertir std :: vector a un argumento arv vector c-estilo
Pregunta
Me gustaría preparar un vector de argumento de la vieja escuela (argv) a utilizar dentro de la función
int execve (const char * nombre, char * Const argv [], char * const envp []);
Lo he probado con la clase STL :: vector:
std::string arguments = std::string("arg1");
std::vector<char*> argv;
char argument[128];
strcpy(argument, arguments.c_str());
argv.push_back(argument);
argv.push_back('\0'); // finish argv with zero
Por último paso el vector a execve ()
execve ( "bashscriptXY", y argv [0], NULL)
El código se compila pero se ARGV "ignorado" por execve (). Por lo tanto, parece estar mal, lo que estoy tratando. ¿Cómo debo construir un ARGV de una manera eficiente con C ++?
Solución
Creo que el char [128] es redundante, ya que la cadena local tendrá la misma vida, también, trate de añadir el programa como argv [0] como rossoft dijo en su respuesta:
const std::string arguments("arg1");
std::vector<const char*> argv;
argv.push_back("bashscriptXY");
// The string will live as long as a locally allocated char*
argv.push_back(arguments.c_str());
argv.push_back(NULL); // finish argv with zero
execve(argv[0], &argv[0], NULL);
Otros consejos
Tenga en cuenta que argv[0]
es siempre el nombre del comando en sí. Así que si quieres pasar 1 parámetro para un programa, usted tiene que llenar dos elementos:
argv[0]
debe ser "bashscriptXY
" (o lo que quieras ...)
argv[1] = "your_argument"
Un par de cuestiones:
- el primer elemento de la matriz
argv
se supone que es el nombre del programa -
argv
el vector puede tomar tiposchar const*
comoexecve()
no modifica los argumentos (aunque el proceso que se invoca puede - pero los habrá copias en su propio espacio de direcciones). Para que pueda empujar cadenasc_str()
en la misma.
Trate de hacer esto:
// unfortunately, execve() wants an array of `char*`, not
// am array of `char const*`.
// So we we need to make sure the string data is
// actually null terminated
inline
std::string& null_terminate( std::string& s)
{
s.append( 1, 0);
return s;
}
// ...
std::string program = std::string( "bashscriptXY");
std::string arg1("arg1");
std::string arg2("arg2");
null_terminate(program);
null_terminate(arg1);
null_terminate(arg2);
std::vector<char *> argv;
argv.push_back( &program[0]);
argv.push_back( &arg1[0]);
argv.push_back( &arg2[0]);
argv.push_back( NULL); // finish argv with zero
intptr_t result = execve( program.c_str(), &argv[0], NULL);
A menos que los argumentos están codificadas, que tendrá que hacer algo de asignación de memoria dinámica. En primer lugar, crear una matriz de punteros a carácter para el número de argumentos, a continuación, asignar memoria para cada argumento y copiar los datos en.
Esta pregunta es muy similar e incluye algunas de las soluciones de código.