Вопрос по emscripten, javascript, node.js, c++, stdin – Как изменить способ ввода в браузере emscripten из window.prompt на что-то более разумное?

4

У меня есть функция C ++, которая когда-то вызывала, потребляет ввод из стандартного ввода. Экспорт этой функции в javascript с использованием emscripten вызывает вызовы window.prompt.

Взаимодействие с подсказкой браузера - действительно утомительная задача. Прежде всего, вы можете вставить только одну строку за раз. Во-вторых, единственный способ указать EOF - нажатьотменить', Последний, но не менее важный способ (в случае моей функции) заставить его перестать запрашивать ввод у пользователя через window.prompt - установить флажок, предотвращающий появление дополнительных запросов.

Для меня лучшим способом ввода было бы чтение какого-нибудь блоба. Я знаю, что могу взломать library.js, но вижу некоторые проблемы:

Чтение BLOB-объектов является асинхронным.Чтобы прочитать BLOB-объект, сначала нужно открыть файл, который пользователь должен выбрать первым.Я нея действительно не знаю, как запретить моей функции читать этот BLOB-объект вечно - здесь нет флажка, как в случае с window.prompt и яЯ не уверен, что если EOF остановит его, это не произойдет.t в случае window.prompt (помогла только проверка флажка).

Лучшим решением будет какой-то обратный вызов, но я хотел бы увидеть подсказки от более опытных пользователей.

не должен»быть очень большим Мы можем смело предположить, что для начала не более 100 КБ. mnowotka
Каков обычно максимальный размер, который мог бы иметь Molfile? abergmeier
Библиотека INCHI:iupac.org/home/publications/e-resources/inchi/download.html, чрезвычайно важный для вычислительной химии. Ввод molfile:en.wikipedia.org/wiki/Structure_data_file#Molfile I 'я пытаюсь экспортироватьprocess_single_input» метод из командной строки программы inchi-1, который вы можете найти в источниках по первой ссылке. mnowotka
Пожалуйста, уточните, какой тип ввода вы обрабатываете и какова общая идея вашего приложения. abergmeier
Вы можете проверить, что я получил здесь:mnowotka.kei.pl/inchi Чтобы запустить экспортированный тип функции в консоли javascript: bla = Module.cwrap ('process_single_input ','строка ','строка») \ n бла ('бла -стдио) mnowotka

Ваш Ответ

2   ответа
0

например, вызвавFS.init в функции предварительного запуска модуля, передавая пользовательскую функцию в качестве стандартного ввода.

var Module = {
  preRun: function() {
    function stdin() {
      // Return ASCII code of character, or null if no input
    }

    var stdout = null; // Keep as default
    var stderr = null;  // Keep as default
    FS.init(stdin, stdout, stderr);
  }
};

Функция довольно низкого уровня: она должна иметь дело с одним символом за раз. Чтобы прочитать некоторые данные из BLOB-объекта, вы можете сделать что-то вроде:

var data = new Int8Array([1,2,3,4,5]);
var blob = new Blob([array], {type: 'application/octet-binary'});
var reader = new FileReader();
var result;
reader.addEventListener("loadend", function() {
  result = new Int8Array(reader.result);
});
var i = 0;
var Module = {
  preRun: function() {
    function stdin() {
      if (if < result.byteLength {
        var code = result[i];
        ++i;
        return code;
      } else {
        return null;
      }
    }

    var stdout = null; // Keep as default
    var stderr = null; // Keep as default
    FS.init(stdin, stdout, stderr);
  }
};

Обратите внимание (как вы намекали), из-за асинхронного характера считывателя может возникнуть условие гонки: считыватель должен быть загружен, прежде чем вы сможете ожидать данные на стандартном входе. Возможно, вам придется реализовать какой-то механизм, чтобы избежать этого в реальном случае. В зависимости от ваших точных требований, вы можете сделать так, чтобы программа Emscripten нена самом деле звонитеmain() пока у вас нет данных:

var fileRead = false;
var initialised = false;
var result;

var array =  new Int8Array([1,2,3,4,5]);
var blob = new Blob([array], {type: 'application/octet-binary'});
var reader = new FileReader();
reader.addEventListener("loadend", function() {
   result = new Int8Array(reader.result);
   fileRead = true;
   runIfCan();
});
reader.readAsArrayBuffer(blob);

var i = 0;
var Module = {
   preRun: function() {
      function stdin() {
         if (i < result.byteLength)
         {
            var code = result[i];
            ++i;
            return code;
         } else{
            return null;
         }
      }

      var stdout = null;
      var stderr = null;
      FS.init(stdin, stdout, stderr);
      initialised = true;
      runIfCan();
   },
   noInitialRun: true
};

function runIfCan() {
   if (fileRead && initialised) {
      // Module.run() doesn't seem to work here
      Module.callMain();
   }
}

Примечание: это версия моего ответа наПредоставление стандартного ввода в HTML-программу emscripten? , но с акцентом на стандартный ввод и добавлением частей о передаче данных из BLOB-объекта.

Здравствуйте, в каком файле я должен переопределить модуль stdin? Jude Maranga
1

Реализуйте выбор файла в Javascript и доступ к нему через JavascriptBlob интерфейс.

Выделите немного памяти вEmscripten

var buf = Module._malloc( blob.size );

Напишите содержание вашегоBlob в возвращенную область памяти из Javascript.

Module.HEAPU8.set( new Uint8Array(blob), buf );

Передайте эту ячейку памяти второмуEmscripten скомпилированная функция, которая затем обрабатывает содержимое файла и

Освободить выделенную память.

Module._free( buf );

Лучше всего читатьвики первый.

Первый пункт прост. У вас есть примеры пунктов 2 и 3? mnowotka
Добавил несколько примеров из вики. abergmeier

Похожие вопросы