MALOUDA-PSA 2024-04-23 12:01 采纳率: 90.9%
浏览 1
已结题

webassembly和js调用的问题2


 23 EMSCRIPTEN_KEEPALIVE
 24 int EncryptionAES(const char * strSrc, const char * gkey, const char* giv, char** str)
 25 {
 26        
 27     
 28         EM_ASM_({
 29             printString(Pointer_stringify($0));
 30             },str);
 31             
 32         return 1;
 33 } 

这里 char** str 是个双重指针,需要先申明一个str指针,然后在 EncryptionAES 里面赋值, 最后返回成功与否,现在问题来了,在 js 里面怎么先申明一个 var jstr; 然后在 EncryptionAES 里面赋值, 然后js 就能使用这个值了

  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-23 12:01
    关注

    引自免费微信小程序:皆我百晓生

    在 JavaScript 中,你需要创建一个数组来接收 WebAssembly 函数返回的 C++ 字符串。这是因为 JavaScript 和 WebAssembly 的内存管理是隔离的,所以你不能直接在 C++ 中修改 JavaScript 的变量。你可以通过以下步骤实现这个功能:

    首先,在 C++ 代码中,你需要接受一个额外的参数,这是一个整数类型的指针,用于指示 JavaScript 传递给你的字符数组的长度。然后,你需要将加密后的字符串复制到这个数组中。

    C++ 代码(修改后的 EncryptionAES):

    #include <emscripten.h>
    #include <string>
    
    EMSCRIPTEN_KEEPALIVE
    int EncryptionAES(const char * strSrc, const char * gkey, const char* giv, char** str, int* length) {
        // ... (你的加密逻辑)
    
        // 假设加密后的字符串为 encryptedStr
        std::string encryptedStr = "your_encrypted_string"; // 替换为实际加密后的字符串
    
        // 复制字符串到 JavaScript 提供的缓冲区
        for (size_t i = 0; i < encryptedStr.size(); ++i) {
            (*str)[i] = encryptedStr[i];
        }
    
        // 设置长度
        *length = encryptedStr.size();
    
        return 1;
    }
    

    接下来,你需要在 JavaScript 中声明一个数组并初始化长度,然后调用 WebAssembly 函数,并处理返回的结果。

    JavaScript 代码:

    // 导入 WebAssembly 模块
    const module = await WebAssembly.compileStreaming(fetch('your_module.wasm'));
    const instance = await WebAssembly.instantiate(module);
    
    let jstr = new Array(100); // 初始长度可设置得大一些,根据实际加密后的字符串长度调整
    let length;
    
    function callEncryptionAES(strSrc, gkey, giv) {
        return new Promise((resolve, reject) => {
            try {
                instance.exports.EncryptionAES(
                    strSrc, 
                    gkey, 
                    giv, 
                    // 使用 Buffer.from 转换字符串为 Uint8Array,以便与 C++ 交互
                    new Uint8Array(jstr),
                    // 获取长度的引用
                    length = new Int32Array(new SharedArrayBuffer(4))[0]
                );
                
                // 如果加密成功(返回值为 1),处理结果
                if (instance.exports.EncryptionAES === 1) {
                    let result = '';
                    for (let i = 0; i < length; i++) {
                        result += String.fromCharCode(jstr[i]);
                    }
                    resolve(result);
                } else {
                    reject("Encryption failed");
                }
            } catch (error) {
                reject(error);
            }
        });
    }
    
    // 使用示例
    callEncryptionAES("your_input_string", "your_key", "your_initialization_vector")
        .then((encryptedStr) => console.log("Encrypted string:", encryptedStr))
        .catch((error) => console.error("Error:", error));
    

    这段代码首先导入 WebAssembly 模块,然后定义了一个名为 callEncryptionAES 的函数,它接受三个字符串作为参数。函数内部使用 WebAssembly.instance.exports.EncryptionAES 来调用 C++ 函数。注意,我们在这里使用了 Uint8ArrayInt32Array 来在 JavaScript 和 WebAssembly 之间安全地传递数据。最后,我们处理加密成功的回调,将加密后的字符串转换回普通字符串并返回。如果加密失败,我们将错误信息返回。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 5月1日
  • 已采纳回答 4月23日
  • 创建了问题 4月23日

悬赏问题

  • ¥15 python点云生成mesh精度不够怎么办
  • ¥15 QT C++ 鼠标键盘通信
  • ¥15 改进Yolov8时添加的注意力模块在task.py里检测不到
  • ¥50 高维数据处理方法求指导
  • ¥100 数字取证课程 关于FAT文件系统的操作
  • ¥15 如何使用js实现打印时每页设置统一的标题
  • ¥15 安装TIA PortalV15.1报错
  • ¥15 能把水桶搬到饮水机的机械设计
  • ¥15 Android Studio中如何把H5逻辑放在Assets 文件夹中以实现将h5代码打包为apk
  • ¥15 使用小程序wx.createWebAudioContext()开发节拍器