Как изменить способ ввода в браузере emscripten из window.prompt на что-то более разумное?

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

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

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

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

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

 abergmeier13 апр. 2013 г., 13:17
Каков обычно максимальный размер, который мог бы иметь Molfile?
 abergmeier13 апр. 2013 г., 09:29
Пожалуйста, уточните, какой тип ввода вы обрабатываете и какова общая идея вашего приложения.
 mnowotka13 апр. 2013 г., 17:20
не должен»быть очень большим Мы можем смело предположить, что для начала не более 100 КБ.
 mnowotka13 апр. 2013 г., 13:04
Вы можете проверить, что я получил здесь:mnowotka.kei.pl/inchi Чтобы запустить экспортированный тип функции в консоли javascript: bla = Module.cwrap ('process_single_input ','строка ','строка») \ n бла ('бла -стдио)
 mnowotka13 апр. 2013 г., 13:01
Библиотека 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, который вы можете найти в источниках по первой ссылке.

Ответы на вопрос(2)

например, вызвав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-объекта.

 Jude Maranga16 мая 2018 г., 07:20
Здравствуйте, в каком файле я должен переопределить модуль stdin?

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

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

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

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

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

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

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

Module._free( buf );

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

 abergmeier14 апр. 2013 г., 11:20
Добавил несколько примеров из вики.
 mnowotka13 апр. 2013 г., 19:13
Первый пункт прост. У вас есть примеры пунктов 2 и 3?

Ваш ответ на вопрос