如何用 webassembly 包装带有 js console.log 函数的 c 函数 printf?

How to wrap with webassembly the c funtion printf with js console.log function?

如何用 console.log 包装 printf() 函数?我想写一个小的 webassembly 演示,但我无法解释以下 js 控制台输出。我用 Clang 将 C 代码编译成 wasm 文件。

C代码:

#include <stdio.h>

int main(void)
{
    printf ("test");
    return 0;
}

JS代码:

  const config = {
    env: {
        memory_base: 0,
        table_base: 0,
        memory: new WebAssembly.Memory({
            initial: 256,
        }),
        table: new WebAssembly.Table({
            initial: 0,
            element: 'anyfunc',
        }),
        printf: msg => console.log(msg),
    }
}

fetch('test.wasm')
    .then(response =>
        response.arrayBuffer()         
    )
    .then(bytes => {
        return WebAssembly.instantiate(bytes, config); 
    })
    .then(results => { 
       var { main } =  results.instance.exports;
       main();
    });

控制台输出始终为:“1024”,与 printf() 输入参数无关。但我想得到字符串 "test" 作为输出。如何解读这个结果?它是指向内存地址的指针吗?当我使用 printf('a') 时,我得到 97 作为控制台输出,即 char 的 ascii 表示。

解法:

let buffer;

const config = {
    env: {
        memory_base: 0,
        table_base: 0,
        memory : new WebAssembly.Memory({ initial: 256}),
        table: new WebAssembly.Table({
            initial: 0,
            element: 'anyfunc',
        }),
        printf: index=> {
            let s = "";
            while(true){
                if(buffer[index] !== 0){
                    s += String.fromCharCode(buffer[index]);
                    index++;
                }else{
                    console.log(s);
                    return;
                }
            }
        }
    }
};

fetch(url)
    .then(response =>{
        return response.arrayBuffer();
    })
    .then(bytes => {
        return WebAssembly.instantiate(bytes, config); 
    })
    .then(results => { 
       let { main } =  results.instance.exports;
       buffer = new Uint8Array(results.instance.exports.memory.buffer);
       main();
    });

WebAssembly 不直接支持字符串类型 - 因此,当编译 printf("test") 语句时,"test" 文字被转换为对线性内存中地址的引用,该地址保存实际字符串。

您必须自己弄清楚如何执行取消引用/编码/解码。有关更多详细信息,请参阅以下内容: