将类型化数组写入子进程标准输入无法正常工作
Writing a typed array to a subprocess stdin isn't working correctly
我正在向子进程的标准输入发送一些数据。数据来自类型化数组。如果更改了类型化数组中的数据,则将截断发送到子进程的数据。我有一个小例子来说明这个问题。
子进程是一个简单的 C++ 应用程序。从 stdin 读取所有数据并将读取的字节数输出到 stdout。 (C++ App 是用 x86_64-w64-mingw32-g++ test.cpp 编译的)C++ 子进程代码:
#include <iostream>
#include <limits>
int main(int argc, char **args) {
std::cin.ignore(std::numeric_limits<std::streamsize>::max());
std::cout << std::cin.gcount() << std::flush;
return 0;
}
nodejs App会循环调用exe。将 128 字节的数据传递给标准输入并检查响应(来自子进程的标准输出)是否为字符串“128”。 nodejs 应用代码:
const execFile = require('child_process').execFile;
var data = new Float64Array(16);
var generateError = true;
generateError && setInterval(_ => {
for (var i = 0; i < 16; i++) {
data[i] = Math.random();
}
}, 1);
setInterval(_ => {
var subproc = execFile('a.exe', [ '-c' ], (error, stdout, stderr) => {
if (stdout.trim() !== '128' || error) {
console.log('ERR: ' + stdout);
} else {
console.log('OK');
}
});
subproc.stdin.write(Buffer.from(data.buffer)) || console.log('Use drain'); // Write Binary Data (128Byte)
subproc.stdin.end();
}, 100);
这给了我一些输出:
OK
OK
OK
OK
OK
OK
ERR: 69
ERR: 114
OK
OK
OK
ERR: 41
是什么让我疯狂:
- 当我将
generateError
设置为 false 时,一切正常。
- 当我使用“
wc.exe -c
”(来自 cgywin 的 Word/Bytecount 工具)时,一切都按预期工作,即使 generateError 设置为 true。
所以问题:怎么了? C++代码? Node Code?传给subproc.stdin.write
后是否不允许改变buffer?如果不允许:为什么使用 wc.exe 的变体?
Windows 下有不同类型的流:二进制流和某些类型的文本流。将c++ App的输入流改为二进制流即可解决问题。 (我猜 wc.exe 会将输入流用作二进制流。这可以解释为什么带有 wc.exe 的变体有效):
#include <iostream>
#include <limits>
#include <fcntl.h>
#include <io.h>
int main(int argc, char **args) {
_setmode(_fileno(stdin), _O_BINARY);
std::cin.ignore(std::numeric_limits<std::streamsize>::max());
std::cout << std::cin.gcount() << std::flush;
return 0;
}
另见 Read binary data from std::cin
我正在向子进程的标准输入发送一些数据。数据来自类型化数组。如果更改了类型化数组中的数据,则将截断发送到子进程的数据。我有一个小例子来说明这个问题。
子进程是一个简单的 C++ 应用程序。从 stdin 读取所有数据并将读取的字节数输出到 stdout。 (C++ App 是用 x86_64-w64-mingw32-g++ test.cpp 编译的)C++ 子进程代码:
#include <iostream>
#include <limits>
int main(int argc, char **args) {
std::cin.ignore(std::numeric_limits<std::streamsize>::max());
std::cout << std::cin.gcount() << std::flush;
return 0;
}
nodejs App会循环调用exe。将 128 字节的数据传递给标准输入并检查响应(来自子进程的标准输出)是否为字符串“128”。 nodejs 应用代码:
const execFile = require('child_process').execFile;
var data = new Float64Array(16);
var generateError = true;
generateError && setInterval(_ => {
for (var i = 0; i < 16; i++) {
data[i] = Math.random();
}
}, 1);
setInterval(_ => {
var subproc = execFile('a.exe', [ '-c' ], (error, stdout, stderr) => {
if (stdout.trim() !== '128' || error) {
console.log('ERR: ' + stdout);
} else {
console.log('OK');
}
});
subproc.stdin.write(Buffer.from(data.buffer)) || console.log('Use drain'); // Write Binary Data (128Byte)
subproc.stdin.end();
}, 100);
这给了我一些输出:
OK
OK
OK
OK
OK
OK
ERR: 69
ERR: 114
OK
OK
OK
ERR: 41
是什么让我疯狂:
- 当我将
generateError
设置为 false 时,一切正常。 - 当我使用“
wc.exe -c
”(来自 cgywin 的 Word/Bytecount 工具)时,一切都按预期工作,即使 generateError 设置为 true。
所以问题:怎么了? C++代码? Node Code?传给subproc.stdin.write
后是否不允许改变buffer?如果不允许:为什么使用 wc.exe 的变体?
Windows 下有不同类型的流:二进制流和某些类型的文本流。将c++ App的输入流改为二进制流即可解决问题。 (我猜 wc.exe 会将输入流用作二进制流。这可以解释为什么带有 wc.exe 的变体有效):
#include <iostream>
#include <limits>
#include <fcntl.h>
#include <io.h>
int main(int argc, char **args) {
_setmode(_fileno(stdin), _O_BINARY);
std::cin.ignore(std::numeric_limits<std::streamsize>::max());
std::cout << std::cin.gcount() << std::flush;
return 0;
}
另见 Read binary data from std::cin