flutter web与c/c++交互
#include <stdio.h> #include <stdlib.h> #include <string.h> #define Export __attribute__((visibility("default"))) __attribute__((used)) extern "C" { struct MAData { int iRetCode; int iBegin; double *pOut; MAData(int iInitSize) { pOut = (double *)malloc(sizeof(double) * iInitSize); } }; Export MAData* getMAData() { MAData* context = new MAData(3); context->iRetCode = 1; context->iBegin = 2; context->pOut[0] = 1.111; context->pOut[1] = 3.14985; context->pOut[2] = 99.551414; return context; } }
以上是c++代码,命名main.cpp,放置在项目文件夹web/js/scripts下, 使用emscripten编译,调用编译命令:
emcc main.cpp -o na.js -s WASM=1 -s EXTRA_EXPORTED_RUNTIME_METHODS="["ccall", "cwrap"]"
生成了na.wasm文件和na.js文件。
下载require.js加载模块,https://requirejs.org/docs/release/2.3.6/minified/require.js
命名require.js,放置到web/js目录下,用于加载na.js,并且在该目录下创建main.js:
define(function(require) { require('./scripts/na'); });
修改web/index.html,加载main.js:
<script src="js/require.js"></script> <script> require(["js/main"]) </script>
至此,整个加载过程完毕。
启动web时,c++代码已经载入,通过flutter调用:
//获取js的全局模块和方法 js.JsObject Module = js.context['Module']; var HEAP8 = Module['HEAP8']; var HEAP32 = Module['HEAP32']; var HEAP64 = Module['HEAPF64']; //获取c++的getMAData方法函数,并且封装成dart函数 js.JsFunction _getMAData = Module.callMethod('cwrap', ['getMAData', '', []]); int getMAData() { return _getMAData.apply([]); } //以下是调用过程, var ret = getMAData();//返回结构体指针地址 var iRetCode= HEAP32[ret >> 2];//获取第一个变量值 var iBegin= HEAP32[ret + 4 >> 2];//获取第二个变量值,因为int是4个自己,所以+4,‘>> 2’是HEAP32固定偏移量,具体原因可以不管 var pOut= HEAP32[ret + 8 >> 2];//获取第三个变量值,该值是指针 for (var i = 0; i < 3; i++) { print(HEAP64[(pOut + (i * 8)) >> 3]); }//获取pOut里的三个值,因为double类型是8个字节,所以每次遍历+8个字节, ‘>> 3’是固定HEAP64固定偏移量,可以不管
至此调用过程结束。
参考文献:
https://www.cntofu.com/book/150/zh/ch2-c-js/ch2-07-ccall-cwrap.md
https://dev.to/kyorohiro/dart-and-c-how-to-ffi-and-wasm-5-structure-and-object-bjd
转载请注明出处,from 博客园HemJohn