Memory 将字符串传递给.wasm模块

Memory 将字符串传递给.wasm模块,memory,native,emscripten,webassembly,Memory,Native,Emscripten,Webassembly,我已经在这个问题上纠缠了一段时间,似乎找不到解决问题的好办法。我来自一个“只有C”的背景,所以大多数web开发人员的东西对我来说都是全新的 我编写了一个C函数float editdestance(char*str1,char*str2),它返回两个char数组的编辑距离。现在的目标是从JS环境中成功调用此函数 在确保代码使用推荐的Emsciptenccall方法后,我决定继续。现在 我使用Emscripten编译C代码,并将标志-O3,-s WASM=1,-s EXPORTED_FUNCTION

我已经在这个问题上纠缠了一段时间,似乎找不到解决问题的好办法。我来自一个“只有C”的背景,所以大多数web开发人员的东西对我来说都是全新的

我编写了一个C函数
float editdestance(char*str1,char*str2)
,它返回两个char数组的编辑距离。现在的目标是从JS环境中成功调用此函数

在确保代码使用推荐的Emscipten
ccall
方法后,我决定继续。现在 我使用Emscripten编译C代码,并将标志
-O3
-s WASM=1
-s EXPORTED_FUNCTIONS=“[''u editDistance']”和
-s SIDE_MODULE=1-s
编译到WASM。我试图围绕我的WebAssembly编写的JS代码是:

// Allocate memory for the wasm module to run in. (65536*256 bit)
let wasmMemory = new WebAssembly.Memory({
    initial: 256
});

let info = {
    env: {
        abort: function() {},
        memoryBase: 0,
        tableBase: 0,
        memory: wasmMemory,
        table: new WebAssembly.Table({initial: 2, element: 'anyfunc'}),
    }
}

// Define the strings
let str1 = "abcd";
let str2 = "abcd";

// Allocate memory on the wasm partition for the HEAPU8
let HEAPU8 = new Uint8Array(wasmMemory.buffer);

// Create the char arrays on the heap from the strings
let stackPtr = 0;
let str1Ptr = stackPtr;
stackPtr = stringToASCIIArray(str1, HEAPU8, stackPtr);

let str2Ptr = stackPtr;
stackPtr = stringToASCIIArray(str2, HEAPU8, stackPtr);

// Read the wasm file and instantiate it with the above environment setup. Then
// call the exported function with the string pointers.
let wasmBinaryFile = 'bin/edit_distanceW.wasm';
fetch(wasmBinaryFile, {credentials:"same-origin"})
    .then((response) => response.arrayBuffer())
    .then((binary) => WebAssembly.instantiate(binary,info))
    .then((wa) => alert(wa.instance.exports._editDistance(str1Ptr, str2Ptr)));

// Converts a string to an ASCII byte array on the specified memory
function stringToASCIIArray(str, outU8Array, idx){
    let length = str.length + 1;

    let i;
    for(i=0; i<length; i++){
        outU8Array[idx+i] = str.charCodeAt(i);
    }
    outU8Array[idx+i]=0;

    return (idx + length);
}
。。并出口这些:

  (export "__post_instantiate" (func 7))
  (export "_editDistance" (func 9))
  (export "runPostSets" (func 6))
  (elem (;0;) (get_global 1) 8 1))
现在,当我测试代码时,字符串会毫无问题地传递给C模块。在事态发展之前,甚至会对它们进行一些函数调用(strLen)。在C函数中有一个讨厌的嵌套循环,它执行主计算,在读取字符串中的字符时遍历2D数组(C代码刚从一篇带有难看伪代码的论文中移植过来,请原谅变量名):

do{

对于(p=0;p如果你刚开始,你可能想使用emscripten生成的JS胶水。也就是说,不要使用SIDE_MODULE=1,而是输出到一个名为.JS的文件。emscripten编译器随后将生成一个.JS和一个.wasm文件。然后你可以在项目中包含.JS文件,它将为你处理所有的加载和设置


如果您尝试自己加载wasm文件,则需要做大量工作来复制emscripten环境,这将需要emscripten的大量内部详细信息。此外,当您更新到新版本的emscripten时,主题的这些内部详细信息会发生更改,因此您需要为自己创建更多工作。

如果您希望尽管如此,看起来您的问题是您正在将memoryBase设置为0,但也尝试使用0作为字符串地址。
memoryBase
告诉侧模块将其全局数据放置在何处。此外,您还需要先调用u post_实例化。谢谢,我已经尝试过emscripten生成了代码,所以我决定继续。然而,您在memoryBase和_post__实例化上的观察让我知道应该研究什么。
  (export "__post_instantiate" (func 7))
  (export "_editDistance" (func 9))
  (export "runPostSets" (func 6))
  (elem (;0;) (get_global 1) 8 1))
do{
    for(p=0; p<editDistance; p++){
        // Do stuff
    }
    // Do more stuff
    editDistance++;
} while(fkp[len2*2-len1][editDistance] != len1);