WebAssembly和c++互相调用的代码实现

参考文档:

4.3 使用C接口导出C++对象-C/C++面向WebAssembly编程

WebAssembly技术_JS调用C函数示例_传递参数、方法导出_DS小龙哥的博客-CSDN博客

  1. 单个lib的调用方法

1.1 单个lib的编译和链接方法

# 把vs的工程转换成cmake工程:(cmake-converter python里面的类似于pip的工具)

cmake-converter -s D:\work\WASM\WASM\Code\path\to\Calc.sln

# 执行cmake,生产.a的静态库:

cd /d D:\work\WASM\WASM\Code\path\to\

## 需要修改

emcmake cmake

## emcmake make_出错,mingw32_ok

emcmake make

mingw32-make

# 生产js和wasm文件:

cd /d D:\work\WASM\WASM\Code\path\to\Calc

emcc -s "EXPORTED_FUNCTIONS=['_fnCalcPlus']" libCalc.a -o libCalc.js

# serve要安装:

npm install -g serve

#运行结果展示:

1.2 几种常见函数的调用方法

 

1.2.1 基本数据类型和调用方法

(1)C/C++链接库代码:

DLL_PUBLIC int fnCalcPlus2(int a, int b);

(2)前端调用代码:

console.log('1+100=:',Module._fnCalcPlus2(1,100));

1.2.2 js传数组到c/c++

(1)C/C++链接库代码:

DLL_PUBLIC int* fnIntArray(int *buff);

(2)前端调用代码:

var buff=_malloc(50)      //申请空间

var out_p=_fnIntArray(buff)  //调用函数

if (out_p == 0) {  //打印结果

console.log('int_array return null')

return;

}

var str = '';

for (var i = 0; i < 10; i++) {

str += Module.HEAP32[(out_p >> 2) + i];

str += ' ';

}

console.log(str);

_free(buff)     //释放空间

1.2.3 js传入c/c++的字符串中文乱码问题

(1)C/C++链接库代码:

DLL_PUBLIC char* fnStrCpy(char *str); // 中文乱码- 不区分平台的字符转换方案;

DLL_PUBLIC void fnStrPrint(char *str);

  1. 前端调用代码:

function runStrcpy(){

var buff=_malloc(500)  //申请空间

var buff1=Module._fnStrCpy(buff)

//c不转成utf,中文会乱码;

console.log('Strcpy UTF8ToString:',UTF8ToString(buff1));  

// c/c++里面是ASCII的中文也是乱码;

console.log('Strcpy AsciiToString:', AsciiToString(buff1));

_free(buff) //释放空间

}

function runStrPrt()

{

//申请空间,存放字符串

var varStr = "from js test js传递给C代码"

var ptr1 = allocate(intArrayFromString(varStr), ALLOC_NORMAL);

//传递给C代码

_fnStrPrint(ptr1)

}

  1. 注意事项:

从js传入c/c++的字符串,需要链接运行时函数;这些函数可以在unexportedRuntimeSymbols 里面找到;增加的链接命令如下:

-s EXPORTED_RUNTIME_METHODS="['allocate','UTF8ToString','intArrayFromString']"

1.2.4 js传入64位的整数,返回值有bug

(1)C/C++链接库代码:

DLL_PUBLIC int64_t i64_add(int64_t a, int64_t b);  // 64位支持有问题;

(2)前端调用代码:

console.log('64位返回值问题:', Module._i64_add(0xFFFFFFFE,0x7FFFFFFF, 1, 0));

(3)原因分析

bug 导出到js会变成: int32_t func(int32_t a_lo, int32_t a_hi, int32_t b_lo, int32_t b_hi)

1.2.5 js获取c++对象和调用对象的方法;

(1)C/C++链接库代码:

DLL_PUBLIC SomeClass *getSomeClass(int a);   // 获取c++对象;

DLL_PUBLIC void delSomeClass(SomeClass *obj);

DLL_PUBLIC int fnSomeClassMethodAdd(SomeClass *obj, int a);

(2)前端调用代码:

var s = Module._getSomeClass(200);

console.log('class add: 200+100=',Module._fnSomeClassMethodAdd(s, 100));

Module._delSomeClass(s);

  1. 个lib调用,c++库依赖其它库
    1. 多个lib的调用编译和链接方法

(1)libtoClassTest.js 调用libtoClassTest.a里面的导出函数fnCalcPlus2;

(2)libtoClassTest.a里面的导出函数fnCalcPlus2调用libLib1Demo.a的fnCalcPlusFromLibDemo函数;

(3) emcc - s "EXPORTED_FUNCTIONS=['_fnCalcPlus2']" - s EXPORTED_RUNTIME_METHODS = "['allocate']" libtoClassTest.a libLib1Demo.a - o libtoClassTest.js

DLL_PUBLIC int fnCalcPlus2(int a, int b);

2.2 多个lib调用遇到的问题

2.2.1 emcc提示错误找不到fnCalcPlusFromLibDemo函数;

原因:(1) sln工程里面生成的是Lib1Demo.lib,而cmake里面是libLib1Demo.a;

(2)emcc没有链接libLib1Demo.a库;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值