【发布时间】:2016-04-17 20:21:07
【问题描述】:
我想从我的 C++ 代码中调用一个 python 脚本。 python 脚本如下所示:
hello.py
#!/usr/bin/python
import sys
print "Hello!"
Readin = sys.stdin.read()
print Readin
C++ 代码来自堆栈溢出的另一个问题。它应该如何工作:
创建一对管道。
使用
fork()创建子进程。child 正在将其管道弯曲到标准输入/标准输出。关闭另一端 并启动脚本。
父亲正在监听管道
read(),接收输入。而在这之后, 发送消息write()。
当输入switch (readResult = read(childToPa... 时,程序不会从fathers 行返回。
我也不知道这个写作部分是否在做它的工作。这样做是一个很有前途的想法,还是有其他可行的可能性? 谢谢!
看起来像:
// 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() )*/
}
【问题讨论】:
-
首先,在另一个程序中运行 Python 代码有什么关系?答:不是。因此,您可以轻松地减少您的代码和问题,更接近于一个最小的示例。然而,即便如此,我想知道你从哪里得到这种方法的想法?它不是新的,不是独特的,实际上已经很成熟了。因此,找到现有的工作示例应该是微不足道的!
-
@Ulrich Eckhardt 该程序集有一个 c++ 核心。这是获得工作的输入。核心是准备这项工作,更新数据库等。在此之后,这项工作将由 python 完成。核心将留在未来。但是将来要做的工作类型会发生变化。所以我们寻找了一种简单的方法来做到这一点。使用 API -> C++ 准备 -> Python 执行输入脚本文件名。有没有更好的方法来执行此操作?我是一名 c 程序员,我不喜欢使用这个 hack。因为这些脚本应该可以相互调用,所以建议使用stdin/put方式。更好的想法?谢谢 =)
标签: python c++ linux stdout stdin