Providing stdin to an emscripten HTML program?

℡╲_俬逩灬. 提交于 2019-11-30 13:45:47

A way would be to use the Emscripten Filesystem API, for example by calling FS.init in the Module preRun function, passing custom functions to be used for standard input, output and error.

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);
  }
};

The functions are quite low-level: they each deal with one character at a time as an ASCII code. If you have strings you want to pass in, you would have to iterate over the characters of the string yourself. I suspect charCodeAt would be helpful. To output strings from stdout or stderr, then I suspect fromCharCode would be helpful.

Example (not very well tested!) implementations using each are below.

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);
  }
};

Rather than editing the output of Emscripten, you could monkey patch the Window object

window.prompt = function() {
  return 'This will appear to come from standard input';
};

Not wonderful, but I would deem this less of a hack than editing the Emscripten-generated Javascript.

According the question "Edit" , I made my function , thx a lot.

Just hope the code below can help someone else.

  1. comment run(); in the end of emscript

    // in my emscript 
    
    // shouldRunNow refers to calling main(), not run().
    var shouldRunNow = true;
    if (Module['noInitialRun']) {
        shouldRunNow = false;
    }
    //run(); // << here
    // {{POST_RUN_ADDITIONS}}
    
  2. result = areaInput(); // As the question mentioned

  3. add the code below in your html file to activate run() in 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>
    
  4. remember io textareas in your html

    <textarea id="input" cols="80" rows="30"></textarea>

    <textarea id="output" cols="80" rows="30"></textarea>

  5. and a button

    <button onclick="execEmscript();">run</button>

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!