我想知道如何从我的C代码使用execl
(或类似)来执行Python(或Lua等)脚本?如何使用EXECL从C代码执行Python脚本?
下面是一些“父母/孩子”代码,显示了我如何使用PIPES向孩子发送数据流。代码可能不完美,但你明白了。注意execl
底部:
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO 1 /* Standard output. */
#define STDERR_FILENO 2 /* Standard error output. */
#define MAXLINE 4096
int main(void){
int n, parent_child_pipe[2], child_parent_pipe[2];
pid_t pid;
char line[MAXLINE];
if (pipe(parent_child_pipe) < 0 || pipe(child_parent_pipe) < 0)
puts("Error creating pipes...\n");
if ((pid = fork()) < 0)
puts("Error forking...\n");
else if (pid > 0) { /* PARENT */
close(parent_child_pipe[0]);
close(child_parent_pipe[1]);
while (fgets(line, MAXLINE, stdin) != NULL) {
n = strlen(line);
if (write(parent_child_pipe[1], line, n) != n)
puts("write error to pipe...\n");
if ((n = read(child_parent_pipe[0], line, MAXLINE)) < 0)
puts("read error from pipe...\n");
if (n == 0) {
puts("child closed pipe...\n");
break;
}
line[n] = 0; /* null terminate */
if (fputs(line, stdout) == EOF)
puts("fputs error...\n");
}
if (ferror(stdin))
puts("fgets error on stdin...\n");
exit(0);
} else { /* CHILD */
close(parent_child_pipe[1]);
close(child_parent_pipe[0]);
if (parent_child_pipe[0] != STDIN_FILENO) {
if (dup2(parent_child_pipe[0], STDIN_FILENO) != STDIN_FILENO)
puts("dup2 error to stdin...\n");
close(parent_child_pipe[0]);
}
if (child_parent_pipe[1] != STDOUT_FILENO) {
if (dup2(child_parent_pipe[1], STDOUT_FILENO) != STDOUT_FILENO)
puts("dup2 error to stdout...\n");
close(child_parent_pipe[1]);
}
**if (execl("./child", "child", (char *) 0) < 0)**
puts("execl error...\n");
}
}
现在的“孩子”的计划上面写的C和只需通过STDIN接收流,操纵流,并将其发回了使用标准输出。
喜欢的东西:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO 1 /* Standard output. */
#define STDERR_FILENO 2 /* Standard error output. */
#define MAXLINE 4096
int main(void){
int n;
char line[MAXLINE];
while ((n = read(STDIN_FILENO, line, MAXLINE)) > 0) {
line[n] = 0; /* null terminate */
n = strlen(line);
if (write(STDOUT_FILENO, line, n) != n)
puts("write error");
}
exit(0);
}
所以这是工作的罚款,但现在我希望能够写孩子的任何脚本语言如Python/Lua的等等。我怎样才能做到这一点?我曾尝试这样的东西:
如果(EXECL( “路径蟒”, “test.py”,(字符*)0)< 0)
但它只是似乎挂等待接收输入?
有人可以帮助我吗?我认为PIPES可以和任何可以从STDIN读取并返回STDOUT的Lua/Python进行通信?
UPDATE:
我已经取得了一些小的变化,现在,这里是Python的文件:“NullFilter.py”,简单地回声它是什么派:
#!/usr/bin/python
import sys
class NullFilter:
def execute(self):
#Read data from STDIN...
data = sys.stdin.read()
#Write data to STDOUT...
sys.stdout.write(data)
exit(0)
if __name__ == '__main__':
nf = NullFilter()
nf.execute()
而且现在的C代码调用使用它:
...
if (execl("/usr/bin/python","./NullFilter.py","./NullFilter.py",NULL, (char *) 0) < 0)
puts("execl error...\n");
...
当我现在运行它,我可以输入文本,标准输入,但是必须击中CRTL-C,看看发生了什么:下面是结果:
[email protected]:~/Desktop/pipe example$ ./parent
hello
hello again
^CTraceback (most recent call last):
File "./NullFilter.py", line 17, in <module>
nf.execute()
File "./NullFilter.py", line 10, in execute
[email protected]:~/Desktop/pipe example$ data = sys.stdin.read()
KeyboardInterrupt
[email protected]:~/Desktop/pipe example$
更新2:
OK,所以我一直在玩弄一点,只是改变了Python代码从 “sys.stdin.read()” 到 “sys.stdin.readline()”它似乎在一定程度上工作,但没有完美...
#!/usr/bin/python
import sys
class NullFilter:
def execute(self):
#Read data from STDIN...
data = ""
for line in sys.stdin.readline():
data = data + line
#Write data to STDOUT...
sys.stdout.write(data)
exit(0)
if __name__ == '__main__':
nf = NullFilter()
nf.execute()
这是一个解决方法,但不完美的。任何其他想法如何让STDIN读取流UNBUFFERED?我已经在Python看了看SELECT模块:
http://docs.python.org/library/select.html
我也试图通过“-u”到Python使“缓冲”,但仍然没有运气;-(
但可以肯定这不能这么难吗?
林顿
只是出于好奇,你为什么不使用Python提供了与C接口API ?您可以使用它直接从C中调用Python代码,而且非常灵活。 – avpx 2010-09-06 18:34:24
您好,我知道Python中的C API,但这不是我正在寻找的。该应用程序实际上是一个C应用程序,我只是*希望*因为我正在使用PIPES,我可以用Python或Lua等其他语言编写一些“用户出口”......但无论如何;-) – 2010-09-07 07:25:34