将stdin提供给emscripten HTML程序?

时间:2015-10-02 16:55:06

标签: javascript emscripten

我有一个C程序,它通过命令行接受一个参数(一个char数组/字符串),并从stdin读取。我使用emscripten将其编译为JavaScript。这是成功的,我可以像使用node.js的普通C程序一样运行它:

emcc -O2 translate.c
node translate.js "foo" < bar.txt

正如你所看到的,我提供了字符串&#34; foo&#34;作为参数和bar.txt的内容为stdin。现在我希望这是一个自包含的HTML文件。

将输出更改为HTML:

emcc -O2 translate.c -o trans.html

我通过adding arguments: ['foo'],var Module中的定义提供论证。这按预期工作,程序正确接收参数。

现在,我如何为此程序提供stdin输入?我不需要动态地执行此操作。只需在HTML中的某个地方声明一个带有所需stdin内容的字符串就可以了。

修改

刚刚找到了适合我的解决方案。在生成的HTML的JS文件中,有一个默认的输入处理程序,当没有定义其他输入方法时,prompt()是用户。只需编辑变量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 个答案:

答案 0 :(得分:6)

一种方法是使用Emscripten Filesystem API,例如通过调用Module preRun函数中的FS.init,传递用于标准输入,输出和错误的自定义函数。

var

这些功能非常低级:它们每个处理一个字符作为ASCII码。如果您想要传入字符串,则必须自己迭代字符串的字符。我怀疑charCodeAt会有所帮助。要从stdout或stderr输出字符串,我怀疑fromCharCode会有所帮助。

使用每个的示例(测试不太好!)实现如下。

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

答案 1 :(得分:0)

您可以修改Window对象

,而不是编辑Emscripten的输出
window.prompt = function() {
  return 'This will appear to come from standard input';
};

并不精彩,但我认为这不仅仅是编辑Emscripten生成的Javascript。

答案 2 :(得分:-1)

根据“编辑”这个问题,我做了很多功能。

希望下面的代码可以帮助其他人。

  1. 评论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}}
    
  2. result = areaInput(); //正如提到的问题

  3. 在html文件中添加以下代码,以激活emscript中的run()

    <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. 在你的HTML中记住io textareas

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

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

  5. 和一个按钮

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