Webassembly embind C++数据结构绑定

1.全局函数

#include <emscripten/val.h>
#include <emscripten/bind.h> 
#include <iostream>
void globalFunction(int i){
    std::cout << "global function call : " << i << std::endl;
    return;
}
EMSCRIPTEN_BINDINGS(Module){
    emscripten::function("globalFunction",&globalFunction);
}

编译指令

emcc .\main.cpp --bind -s WASM=1 -s EXPORT_ES6 -o wasm.js

生成文件 wasm.js wasm.wasm

js调用方式

import WasmModule from "./wasm.js"
WasmModule().then((Instance)=>{
    Instance.globalFunction(6);
})

输出结果:

global function call : 6

2.结构体

struct Point{
    double x;
    double y;
};
void globalFunction(const Point& point){
    std::cout << "x : " << point.x  << " y: " << point.y  << std::endl;
    return;
}
EMSCRIPTEN_BINDINGS(Module){
    emscripten::function("globalFunction",&globalFunction);
    emscripten::value_object<Point>("Point")
    .field("x",&Point::x)
    .field("y",&Point::y);
}

js调用方式

import WasmModule from "./wasm.js"
WasmModule().then((Instance)=>{
    let point  = {x: 20,y:30};     //构造Point
    Instance.globalFunction(point);
})

输出结果:

x : 20 y: 30

如果c++返回Point结构体,js直接Point.x,Point.y解析即可

3.枚举

enum COLOR{
    BLUE,
    RED,
    WHITE,
};
EMSCRIPTEN_BINDINGS(Module){
    emscripten::enum_<COLOR>("COLOR")
    .value("BLUE",BLUE)
    .value("RED",RED)
    .value("WHITE",WHITE);
}

js调用方式

import WasmModule from "./wasm.js"
WasmModule().then((Instance)=>{
    let blue = Instance.COLOR.BLUE;
    console.log(blue.value);
    let red = Instance.COLOR.RED;
    console.log(red.value);
})

输出结果:

0
1

4.类

class Point{
public:
    Point(double x,double y){
        this->x = x;
        this->y = y;
    }
    Point(){
        this->x = 0;
        this->y = 0;
    }
    double getX() const{
        return this->x;
    }
    double getY() const{
        return this->y;
    }
    Point& Add(const Point* pt){
        if(pt == nullptr){
            return *this;
        }
        this->x = pt->getX();
        this->y = pt->getY();
        return *this;
    }
    static void testStaticFunc(){
        std::cout << "testStaticFunc call" << std::endl;
    }
private:
    double x;
    double y;
};
EMSCRIPTEN_BINDINGS(Module){
    emscripten::class_<Point>("Point")
    .constructor<>()
    .constructor<double,double>()    //可以有多个构造函数
    .function("getX",&Point::getX)    //普通成员函数
    .function("getY",&Point::getY)
    .class_function("testStaticFunc",&Point::testStaticFunc)   //类静态成员函数
    .function("Add",&Point::Add,emscripten::allow_raw_pointers());  //这个函数只是想展示如果函数参数带指针,如何绑定
}

js调用方式

import WasmModule from "./wasm.js"
WasmModule().then((Instance)=>{
    let point = new Instance.Point(50,60);
    console.log(point.getX());
    console.log(point.getY());
    Instance.Point.testStaticFunc();
})

输出结果:

50
60
testStaticFunc call

5.std::vector

EMSCRIPTEN_BINDINGS(Module){
    emscripten::class_<Point>("Point")
    .constructor<>()
    .constructor<double,double>()
    .function("getX",&Point::getX)
    .function("getY",&Point::getY)
    .class_function("testStaticFunc",&Point::testStaticFunc)
    .function("Add",&Point::Add,emscripten::allow_raw_pointers());    //这是之前的Point类

    //注册vector类
    emscripten::register_vector<Point>("vector_Point");     //这里的Point就是前面的Point类
}

js调用方式:

import WasmModule from "./wasm.js"
WasmModule().then((Instance)=>{
    let point1 = new Instance.Point(50,60);
    let point2 = new Instance.Point(90,100);
    let vecPoint = new Instance.vector_Point;
    vecPoint.push_back(point1);
    vecPoint.push_back(point2);
    
    console.log(vecPoint.size());
    let testPoint = vecPoint.get(1);
    console.log("x : ",testPoint.getX()," y:",testPoint.getY());
})

输出结果:

2
x :  90  y: 100

如果在js中new C++中的对象,由于对象的内存是开辟在webassembly实例的线性内存中的,不会进行内存回收,所以需要手动释放。下篇文章讲如何释放内存。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值