当我快速地将大量数据写入C子进程时,我遇到了一个断管错误。在
所以我从python脚本运行一个c子进程:
process = subprocess.Popen("./gpiopwm", stdin=subprocess.PIPE)
while True:
process.stdin.write("m2000\n")
print "bytes written"
gpiopwm.c主回路截面:
^{pr2}$但是,其输出如下:
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
显然,C程序在fgets
行中断,因为2
从未被打印出来。
我做错了什么?我怎样才能避免这种情况?在
编辑:
我已经更新了fgets
行,使其不包含取消引用参数,但仍然得到断开管道错误。在
编辑:
input
初始化为char *input="m2000";
如果您尝试从控制台运行C程序,您将看到它崩溃。如果您在调试器中运行,您将看到它位于以下行:
似乎
input
是一个字符数组,当你用*input
取消对它的引用时,传递的不是指针而是一个char
值。这会导致未定义的行为和崩溃。在如果不是错误的话,那一行应该会给你一个很大的来自编译器的警告消息。不要忽视警告信息,它们通常是你做错事的一个指示器,而且可能是危险的。在
一般提示:当开发一个应该从另一个程序调用的程序时,就像您在这里所做的那样,首先测试该程序以确保它能正常工作。如果它不起作用,那就先解决它。在
最后一个提示:请记住,^{} 在目标字符串中包含了新行。您可能需要检查它,如果它在那里,请将其删除。在
在最后一次编辑中,显示了
input
的声明,我们知道了real的问题:您试图修改常量数据,同时也希望写入超出数据边界的内容。在当你使
input
指向一个文本字符串时,你必须记住所有的文本字符串都是只读的,你不能修改文本字符串。试图这样做是未定义的行为。更糟糕的是,您的字符串只有6个字符长,但您尝试写入7个字符。在首先更改
^{pr2}$input
的声明和初始化:这将声明它为一个数组,位于堆栈上,可以修改。那就去吧
这可以完成两件事:首先,通过使用
sizeof(input)
作为大小,可以确保fgets
永远不会写越界。其次,通过在循环条件中使用fgets
调用,当Python脚本被中断时,循环将结束,并且您不会永远无法读取任何内容,然后处理从未读过的数据。在相关问题 更多 >
编程相关推荐