WebAssembly002 emcc Emscripten js端传入数组给c++

发布时间:2024年01月23日

Emscripten下载

简单Demo

#include <stdio.h>
#include <emscripten/emscripten.h>
    
int main(int argc, char ** argv) {
    printf("Hello World\n");
}
    
#ifdef __cplusplus
extern "C" {
#endif
    
EMSCRIPTEN_KEEPALIVE void myFunction(int argc, char ** argv) {
    printf("MyFunction Called\n");
}
    
#ifdef __cplusplus
}
#endif
  • CMakeLists.txt

cmake_minimum_required(VERSION 3.17)
project(WASM)
    
set(CMAKE_CXX_STANDARD 14)
    
add_executable(WASM main.cpp)

EMSCRIPTEN_KEEPALIVE(重要)

  • EMSCRIPTEN_KEEPALIVE:此宏用于声明在JavaScript中可访问的函数。通过在函数定义前使用此宏,您可以确保函数不会被优化和删除。
EMSCRIPTEN_KEEPALIVE
void myFunction() {
  // Function body
}

emscripten_run_script*

  • emscripten_run_script:此函数用于在JavaScript环境中执行一段脚本。
emscripten_run_script("console.log('Hello, Emscripten!')");

emscripten_async_wget*

  • emscripten_async_wget:此函数用于异步下载文件。
void downloadFile() {
  emscripten_async_wget("https://example.com/file.txt", "file.txt", onComplete, onError);
}

void onComplete() {
  printf("File downloaded successfully.\n");
}

void onError() {
  printf("Error downloading file.\n");
}

emscripten_set_main_loop*

  • emscripten_set_main_loop:此函数用于设置一个主循环,它将在每个帧上运行。
void mainLoop() {
  // Main loop body
}

int main() {
  emscripten_set_main_loop(mainLoop, 0, 1);
  return 0;
}

使用emscripten.h 处理js输入的数组并返回处理的数组

  • 下面是一个完整的例子,演示了如何使用emscripten.h处理JavaScript输入的数组,并返回处理的数组:
#include <emscripten.h>

// 定义一个处理数组的函数
int squareNumber(int num) {
    return num * num;
}

// 定义一个可以在JavaScript中调用的函数
EMSCRIPTEN_KEEPALIVE
int* processArray(int* inputArray, int length) {
    // 为输出数组分配内存
    int* outputArray = (int*) malloc(length * sizeof(int));

    // 处理输入数组,并将结果存储在输出数组中
    for (int i = 0; i < length; i++) {
        outputArray[i] = squareNumber(inputArray[i]);
    }

    // 返回处理后的数组
    return outputArray;
}

int main() {
    return 0;
}
  • 使用Emscripten编译器将该代码编译为WebAssembly模块:
emcc main.cpp -o example.html -s EXPORTED_FUNCTIONS='["_processArray","_malloc"]' -s EXPORTED_RUNTIME_METHODS='["ccall"]'

在这里插入图片描述

  • 在JavaScript中使用编译好的WebAssembly模块:
// 加载WebAssembly模块
const wasmModule = require('./example.js');

// 定义一个输入数组
let inputArray = [1, 2, 3, 4, 5];

// 将输入数组转换为C中的格式(使用EM_ASM将其传递给C)
let inputArrayPointer = Module._malloc(inputArray.length * Int32Array.BYTES_PER_ELEMENT);
Module.HEAP32.set(inputArray, inputArrayPointer / Int32Array.BYTES_PER_ELEMENT);



// 调用C函数来处理输入数组(使用Module.ccall)
const outputArrayPointer = Module.ccall('processArray', 'number', ['number', 'number'], [inputArrayPointer, inputArray.length]);

// 获取处理后的数组
let outputArray =  Module.HEAP32.subarray(outputArrayPointer / Int32Array.BYTES_PER_ELEMENT, outputArrayPointer / Int32Array.BYTES_PER_ELEMENT + inputArray.length);

// 将输出数组从C格式转换为JavaScript格式(使用Array.from)
const outputJsArray = Array.from(outputArray);

let outputJsArray = Array.from(outputArray);
// 打印输出数组
console.log(outputJsArray);

Module._free(inputArrayPtr);
Module._free(outputArrayPtr);
  • 代码首先加载了编译好的WebAssembly模块,然后定义了一个输入数组。接下来,使用模块的_malloc函数将输入数组分配在内存中,并将其指针传递给C函数。使用ccall函数调用C函数来处理输入数组,并获取处理后的数组的指针。最后,将输出数组从C格式转换为JavaScript格式,并打印了输出数组。

cg

let inputArray = [1, 2, 3, 4, 5];let inputArrayPointer = Module._malloc(inputArray.length * Int32Array.BYTES_PER_ELEMENT);
Module.HEAP32.set(inputArray, inputArrayPointer / Int32Array.BYTES_PER_ELEMENT);const outputArrayPointer = Module.ccall('hf_play_start_train', 'number', ['number', 'number'], [inputArrayPointer,1]);
文章来源:https://blog.csdn.net/ResumeProject/article/details/132544999
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。