Предоставление стандартного ввода в HTML-программу emscripten?
У меня есть программа на C, которая принимает один аргумент (массив / строку char) через командную строку, а также читает из стандартного ввода. Я скомпилировал его в JavaScript с помощью emscripten. Это было успешно, и я могу запустить его так же, как обычную программу на C, используя node.js:
emcc -O2 translate.c
node translate.js "foo" < bar.txt
Как видите, я предоставляю строку "foo" в качестве аргумента, а содержимое bar.txt - в качестве stdin. Теперь я хочу, чтобы это был отдельный HTML-файл.
Изменяя вывод на HTML:
emcc -O2 translate.c -o trans.html
Я предоставляю аргумент, добавляяarguments: ['foo'],
к определениям в var Module
, Это работает, как и ожидалось, программа получает аргумент правильно.
Теперь, как мне предоставить ввод stdin для этой программы? Мне не нужно делать это динамически. Было бы хорошо просто объявить строку где-нибудь в HTML с требуемым содержимым stdin.
редактировать
Только что нашел решение, которое работает для меня. В файле JS для сгенерированного HTML есть обработчик ввода по умолчанию, который prompt()
s пользователь, когда никакой другой метод ввода не определен. Просто отредактируйте переменную result
или вызовите свою собственную функцию:
} else if (typeof window != 'undefined' &&
typeof window.prompt == 'function') {
// Browser.
// REPLACE THIS CODE:
result = window.prompt('Input: '); // returns null on cancel
if (result !== null) {
result += '\n';
}
3 ответа
Можно было бы использовать API файловой системы Emscripten, например, вызвав FS.init в функции preRun модуля, передавая пользовательские функции, которые будут использоваться для стандартного ввода, вывода и ошибки.
var Module = {
preRun: function() {
function stdin() {
// Return ASCII code of character, or null if no input
}
function stdout(asciiCode) {
// Do something with the asciiCode
}
function stderr(asciiCode) {
// Do something with the asciiCode
}
FS.init(stdin, stdout, stderr);
}
};
Функции довольно низкоуровневые: каждая из них имеет дело с одним символом за раз как с кодом ASCII. Если у вас есть строки, которые вы хотите передать, вам придется самим перебирать символы строки. Я подозреваю, что charCodeAt будет полезным. Для вывода строк из stdout или stderr, я подозреваю, что было бы полезно из CharCode.
Примеры (не очень хорошо протестированные!) Реализаций, использующих каждую, приведены ниже.
var input = "This is from the standard input\n";
var i = 0;
var Module = {
preRun: function() {
function stdin() {
if (i < res.length) {
var code = input.charCodeAt(i);
++i;
return code;
} else {
return null;
}
}
var stdoutBuffer = "";
function stdout(code) {
if (code === "\n".charCodeAt(0) && stdoutBuffer !== "") {
console.log(stdoutBuffer);
stdoutBufer = "";
} else {
stdoutBuffer += String.fromCharCode(code);
}
}
var stderrBuffer = "";
function stderr(code) {
if (code === "\n".charCodeAt(0) && stderrBuffer !== "") {
console.log(stderrBuffer);
stderrBuffer = "";
} else {
stderrBuffer += String.fromCharCode(code);
}
}
FS.init(stdin, stdout, stderr);
}
};
Вместо того, чтобы редактировать вывод Emscripten, вы могли бы обезьяна исправить объект Window
window.prompt = function() {
return 'This will appear to come from standard input';
};
Не удивительно, но я бы посчитал это менее взломанным, чем редактирование сгенерированного Emscripten Javascript.
По вопросу "Редактировать" я сделал свою функцию, спасибо.
Просто надеюсь, что приведенный ниже код может помочь кому-то еще.
комментарий run(); в конце emscript
// in my emscript // shouldRunNow refers to calling main(), not run(). var shouldRunNow = true; if (Module['noInitialRun']) { shouldRunNow = false; } //run(); // << here // {{POST_RUN_ADDITIONS}}
result = areaInput();
// В качестве упомянутого вопросадобавьте приведенный ниже код в ваш HTML-файл, чтобы активировать run () в emscript
<script> var message; var point = -1; function getArea(){ message = document.getElementById('input').value.split('\n'); } function areaInput(){ if(point >= message.length - 1){ return null; } point += 1; return message[point]; } function execEmscript(){ window.console = { log: function(str){ document.getElementById("output").value += "\n" + str; } } getArea(); run(); } </script>
помните io textareas в вашем html
<textarea id="input" cols="80" rows="30"></textarea>
<textarea id="output" cols="80" rows="30"></textarea>
и кнопка
<button onclick="execEmscript();">run</button>