Python中的C子进程:sub.stdin.write IOError BREAKED Pipe
在将大量数据非常快速地写入C子进程时,我遇到了断管错误 因此,我使用python脚本运行c子流程:Python中的C子进程:sub.stdin.write IOError BREAKED Pipe,python,c,subprocess,broken-pipe,Python,C,Subprocess,Broken Pipe,在将大量数据非常快速地写入C子进程时,我遇到了断管错误 因此,我使用python脚本运行c子流程: process = subprocess.Popen("./gpiopwm", stdin=subprocess.PIPE) while True: process.stdin.write("m2000\n") print "bytes written" gpiopwm.c主回路的区段: printf("1\n"); while (1) { fgets(input,7,s
process = subprocess.Popen("./gpiopwm", stdin=subprocess.PIPE)
while True:
process.stdin.write("m2000\n")
print "bytes written"
gpiopwm.c主回路的区段:
printf("1\n");
while (1) {
fgets(input,7,stdin); // Takes input from python script
printf("2\n");
numbers = input+1; // stores all but first char of input
char first = input[0]; // stores first char of input
if (first=='m') {
printf("3\n");
printf("%s\n",numbers);
}
}
然而,这项研究的结果如下:
1
bytes written
Traceback (most recent call last):
File "serial-receive-to-pwm.py", line 20, in <module>
process.stdin.write("m2000\n")
IOError: [Errno 32] Broken pipe
1
写入的字节数
回溯(最近一次呼叫最后一次):
文件“串行接收到pwm.py”,第20行,输入
process.stdin.write(“m2000\n”)
IOError:[Errno 32]管道破裂
C程序显然在fgets
行中断,因为2
从未打印。
我做错了什么?我怎样才能避免这种情况
编辑:
我已经更新了fgets
行,这样它就不包括dereference参数,但仍然会得到断管错误
编辑:
input
初始化为char*input=“m2000”代码>如果尝试从控制台运行C程序,您将看到它崩溃。如果在调试器中运行,您将看到它位于以下行:
fgets(*input,7,stdin);
似乎input
是一个字符数组,当您使用*input
解除对它的引用时,您传递的不是指针,而是单个字符
值。这会导致未定义的行为和崩溃
如果不是一个错误,那么这一行应该给你一条来自编译器的非常大的警告消息。不要忽视警告信息,它们通常是你做错事的指示器,可能是危险的
一般提示:当开发一个应该从另一个程序调用的程序时,就像您在这里所做的那样,首先测试该程序以确保它工作正常。如果它不工作,那么首先修复它
最后一个提示:记住在目标字符串中包含换行符。您可能需要检查它,如果它在那里,请将其删除
在最后一次编辑中,显示了input
的声明,我们知道了真正的问题:您试图修改常量数据,并且您还希望写入超出数据边界的数据
当您使input
指向文字字符串时,必须记住所有文字字符串都是只读的,不能修改文字字符串。试图这样做是未定义的行为。更糟糕的是,您的字符串只有六个字符长,但您尝试向其写入七个字符
首先更改输入的声明和初始化
:
char input[16] = "m2000\n";
这将声明它为一个数组,位于堆栈上,可以修改。那就做吧
while (fgets(input, sizeof(input), stdin) != NULL) { ... }
这实现了两件事:首先,通过使用sizeof(input)
作为大小,可以确保fgets
永远不会写越界。其次,通过使用fgets
在循环条件中调用,当Python脚本被中断时,循环将结束,并且您不会永远循环,无法读取任何内容,然后处理从未读取过的数据。如果()也显式地告诉OP如何解决此问题,不是很好吗?;-)我已经说过错误在fgets行中。编译器工作正常,否则就不会编译。@theoB610:假设char输入[至少7]代码>同时尝试以下操作:fgets(输入,7,标准输入)代码>@theoB610只是不使用解引用运算符。@theoB610更新了我的答案,请查看其底部。请显示输入的完整声明(以及可能的初始化)
。