Ich möchte ein Python Skript von meinem C++ Code aufrufen. Der Python-Skript wie folgt aussieht:C++ starte ein Skript (bash, python ...) und benutze stdin/stdout für datatransfare [linux]
hello.py
#!/usr/bin/python
import sys
print "Hello!"
Readin = sys.stdin.read()
print Readin
Der C++ Code aus einer anderen Frage aus Stapelüberlauf ist. Wie es funktionieren sollte:
Erstellen eines Paares von Rohren.
Erstellen eines untergeordneten Prozesses mit
fork()
.kind verbiegt seine rohre zu stdin/stdout. Schließen Sie die anderen Enden und starten Sie das Skript.
Vater hört auf die Rohre
read()
, empfangenden Eingang. Und danach Senden einer Nachrichtwrite()
.
Das Programm kehrt nicht von Väter Linie, wenn switch (readResult = read(childToPa...
eingegeben wird.
Ich weiß auch nicht, ob dieses Schreibgerät seinen Job macht. Ist das eine vielversprechende Idee, oder gibt es andere Arbeitsmöglichkeiten? Danke!
Es sieht aus wie:
// maybe not all includes are necessary
#include <iostream>
#include <fstream>
#include <string>
#include <errno.h>
#include <sys/stat.h> // mkdir
#include <stdlib.h> // system()
#include <unistd.h> // rmdir
#include <cstring> // memset
// wait:
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
int main() {
char target[] = "./hello.py";
enum PIPE_FILE_DESCRIPTERS {
READ_FD = 0, WRITE_FD = 1
};
enum CONSTANTS {
BUFFER_SIZE = 100
};
int parentToChild[2];
int childToParent[2];
pid_t pid;
string dataReadFromChild;
char buffer[BUFFER_SIZE + 1];
memset(buffer,0x00,BUFFER_SIZE + 1);
ssize_t readResult;
int status;
int retPipe1 = pipe(parentToChild);
int retPipe2 = pipe(childToParent);
switch (pid = fork()) {
case -1:
printf("Fork failed");
exit(-1);
case 0: /* Child will start scripts*/
{
// Bending stdin/out to the pipes?
int retdup21 = dup2(parentToChild[READ_FD], STDIN_FILENO);
int retdup22 = dup2(childToParent[WRITE_FD], STDOUT_FILENO);
int retdup23 = dup2(childToParent[WRITE_FD], STDERR_FILENO);
// Close in this Process the other sides of the pipe
int retclose1 = close(parentToChild[WRITE_FD]);
int retclose2 = close(childToParent[READ_FD]);
int retexe = execlp(target ," "); // warning not enough variable arguments to fit a sentinel [-Wformat=]
printf("This line should never be reached!!!"); // why? what happens if execlp finishes?
exit(-1);
break; // to make the compiler happy =)
}
default: /* Parent */
cout << "Child " << pid << " process running..." << endl;
// close the other ends of the pipe from the other process.
int retdup21 = close(parentToChild[READ_FD]);
int retdup22 = close(childToParent[WRITE_FD]);
// readtry
while (true) {
switch (readResult = read(childToParent[READ_FD], buffer, 1)) // execution does not return from this function.
{
case 0: /* End-of-File, or non-blocking read. */
{
cout << "End of file reached..." << endl << "Data received was (" << dataReadFromChild.size() << "):" << endl
<< dataReadFromChild << endl;
cout << "starting writing" << endl;
char bufferW[] = "{\"AElement\":\"Something\"}\0";
int writeResult = write(parentToChild[WRITE_FD],bufferW,sizeof(bufferW));
int saveerrno = errno;
if(-1 == writeResult)
{
cout << "errno while writing: " << errno << std::endl;
if (9 == saveerrno)
cout << "Errno Bad File descriptor" << endl;
}
cout << "Write Result: " << writeResult << std::endl;
int retWait = waitpid(pid, &status, 0);
cout << endl << "Child exit staus is: " << WEXITSTATUS(status) << endl << endl;
exit(0);
}
case -1:
{
if ((errno == EINTR) || (errno == EAGAIN)) {
errno = 0;
break;
} else {
printf("read() failed");
exit(-1);
}
}
default:
dataReadFromChild.append(buffer, readResult);
printf("%s",buffer);
memset(buffer,0x00,BUFFER_SIZE + 1);
break;
}
} /* while (true) */
} /* switch (pid = fork())*/
}
Erstens: Wie ist es relevant, dass Sie in dem anderen Programm Python-Code ausführen? Antwort: Es ist nicht. So könnten Sie Ihren Code und Ihre Frage leicht reduzieren, indem Sie sich einem minimalen Beispiel nähern. Aber selbst dann frage ich mich, woher du die Idee für den Ansatz hast? Es ist nicht neu, nicht einzigartig und tatsächlich gut etabliert. Es sollte also trivial sein, existierende, funktionierende Beispiele zu finden! –
@Ulrich Eckhardt Die Baugruppe hat einen C++ - Kern. Dies erhält eine Eingabe für einen Job. Der Kern bereitet diesen Job vor, aktualisiert die Datenbank usw. Danach wird der Job von python ausgeführt. Der Kern bleibt für die Zukunft. Aber die Art von Aufgaben wird sich in Zukunft ändern. Also haben wir nach einem einfachen Weg gesucht. Geben Sie den Scriptfile-Namen mit API ein -> C++ preparing -> Python doing. Gibt es einen besseren Weg, dies zu erreichen? Ich bin ein Programmierer, und ich bevorzuge diesen Hack nicht. Da diese Skripte möglich sein sollten, von einander aufgerufen zu werden, wurde der stdin/put-Weg vorgeschlagen. Bessere Ideen? Thx =) –