在typescript浏览器端中调用C++编写的函数,WebAssembly传递指针类型的参数,以及处理指针类型的返回值。

首先要在Cmake工程中的cmakelists.txt文件中引入Emscripten工具链:

set(CMAKE_TOOLCHAIN_FILE "D:/CppPkg/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake")

直接看C++代码:

#include <emscripten/emscripten.h>
#include <cstdlib>extern "C" {struct DataResult {double* dArr;int propCount;};EMSCRIPTEN_KEEPALIVEdouble sumArray(double* fArr, int arrLen) {double sum = 0.0;for (int i = 0; i < arrLen; i++) {sum += fArr[i];}return sum;}EMSCRIPTEN_KEEPALIVEdouble* vectorSum(double* vectorA, double* vectorB, int vecLen) {double* resArr = (double*)malloc(vecLen * sizeof(double));for (int i = 0; i < vecLen; i++) {resArr[i] = vectorA[i] + vectorB[i];}return resArr;}EMSCRIPTEN_KEEPALIVEDataResult* createDataResult(double* dArr, int propCount) {DataResult* dtRes = (DataResult*)malloc(sizeof(DataResult));dtRes->dArr = dArr;dtRes->propCount = propCount;return dtRes;}EMSCRIPTEN_KEEPALIVEdouble* allocateDoubleMemory(int size) {return (double*)malloc(size * sizeof(double));}EMSCRIPTEN_KEEPALIVEvoid freeMemory(void* dataPtr) {free(dataPtr);}
}

通过em++命令,生成MyLib.js和MyLib.wasm文件

em++ MyLib.cpp -O2 -o MyLib.js -s WASM=1 -s MODULARIZE=1 -s EXPORT_NAME="MyLibModule" -s "EXPORTED_FUNCTIONS=['_sumArray']" -s "EXPORTED_RUNTIME_METHODS=['ccall', 'cwrap']"

在WASMTest.ts中编写代码:

type ImportObject = WebAssembly.Imports;interface MyLibModule{sumArray: (fArr: number, arrLen: number) => number;allocateDoubleMemory: (size: number) => number;freeMemory: (dataPtr: number) => void;vectorSum: (vectorA: number, vectorB: number, vecLen: number) => number;createDataResult: (dArrPtr: number, propCount: number) => number;memory: WebAssembly.Memory;}async function loadWasmModule(memory: WebAssembly.Memory): Promise<MyLibModule>{const importObject: WebAssembly.Imports = {env: {memory: memory,emscripten_resize_heap: () => {console.log("emscripten_resize_heap called");return true;  // 这里可以返回 true 或者处理扩展内存的逻辑},}};const response = await fetch('src/lib/wasm/MyLib.wasm');const buffer = await response.arrayBuffer();const module = await WebAssembly.instantiate(buffer, importObject);return module.instance.exports as unknown as MyLibModule;}async function useModule(){const memory = new WebAssembly.Memory({ initial: 20, maximum: 1000 });const wasmModule = await loadWasmModule(memory);const pageSize = 64 * 1024;const totalMemory = memory.buffer.byteLength;const totalPages = totalMemory/pageSize;console.log(`Total memory: ${totalMemory} bytes (${totalPages} pages)`)memory.grow(100);console.log(`New total memory size: ${memory.buffer.byteLength} bytes`);const vecA = new Float64Array([1,2,3,4,5,6,9,12]);const vecB = new Float64Array([1,2,3,4,5,6,6,14]);const vecAptr = wasmModule.allocateDoubleMemory(vecA.length * 8);const vecBptr = wasmModule.allocateDoubleMemory(vecB.length * 8);const memoryBuffer = wasmModule.memory.buffer;const wasmVecA = new Float64Array(memoryBuffer, vecAptr, vecA.length);const wasmVecB = new Float64Array(memoryBuffer, vecBptr, vecB.length);wasmVecA.set(vecA);wasmVecB.set(vecB);const resultPtr = wasmModule.vectorSum(vecAptr, vecBptr, vecA.length);const wasmRes = new Float64Array(memoryBuffer, resultPtr, vecA.length);console.log(wasmRes)wasmModule.freeMemory(vecAptr);wasmModule.freeMemory(vecBptr);wasmModule.freeMemory(resultPtr);// 传递数组,返回结构体指针,从结构体指针中取数据。const dArr = new Float64Array([5,4,7,1,9,3,5]);const dArrPtr = wasmModule.allocateDoubleMemory(dArr.length * 8);const wasmdArr = new Float64Array(memoryBuffer, dArrPtr, dArr.length);wasmdArr.set(dArr);const resPtr = wasmModule.createDataResult(dArrPtr, dArr.length);const dataView = new DataView(memoryBuffer);const dArrResPtr =  Number(dataView.getUint32(resPtr, true));const propCount = dataView.getInt32(resPtr+4, true);const resdArr = new Float64Array(memoryBuffer, dArrResPtr, propCount);console.log(`return struct DataResult dArr Pointer is ${dArrResPtr}`);console.log(`the struct DataResult dArr value is: `);console.log(resdArr);wasmModule.freeMemory(dArrPtr);wasmModule.freeMemory(resPtr);}
useModule();

查看浏览器打印结果:

在这里插入图片描述

第一个例子:在这里,我们传递了2个双精度浮点的数组,传递进入C++函数,然后给两个数组求和,返回的是double*类型的指针。
第二个例子:
最后是返回一个C++结构体指针,在TypeScript中通过DataView来获取内存中的地址偏移量来取得结构体中的数据,因为em++编译器是以32位来编译.cpp文件的,所以指针占4个字节。DataResult结构体第一个属性dArr是一个指针,那么就是地址偏移量0,然后以32位无符号整型取得dArr指针,通过这个指针去读取wasm中memoryBuffer中的数据,就可以得到dArr属性对应的值了。同理,通过地址偏移量+4来得到propCount属性,以32位整数读取数据即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/142395.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

鸿蒙开发之ArkTS 基础六 对象

什么是对象的呢&#xff1f;就是描述物体的特征和行为&#xff0c;是可以存储多种数据的容器 对象的定义和使用 let 对象名称: 对象结构类型 值 通过interface 关键字来约定对象结构类型,语法结构如下&#xff1a; interface 对象名{ 属性1&#xff1a;类型 属性2&#…

11.01类的定义和对象的使用(练习)

类的定义 类名&#xff1a;手机(Phone) 成员变量&#xff1a;品牌(brand&#xff09;&#xff0c;价格&#xff08;price&#xff09; 成员方法&#xff1a;打电话(calL)&#xff0c;发短信&#xff08;sendMessage&#xff09; 调用类变量和方法

基于SpringBoot+Vue+MySQL的高校心理教育辅导系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着社会的快速发展&#xff0c;大学生群体面临着日益复杂的学习、生活及就业压力&#xff0c;心理健康问题日益凸显。传统的面对面心理咨询方式因时间、空间等限制&#xff0c;难以满足学生多样化的需求。因此&#xff0c;利用…

基于spring的ssm整合

目录 基于spring的ssm整合 Spring 框架 SpringMVC 框架 MyBatis 框架 1.创建项目 2.导入依赖 3.导入sql 4.创建jdbc.propries文件 1&#xff09;mysql8以下 2&#xff09;mysql8以上的 5.创建mybatis-config.xml配置文件 6.创建spring-Config.xml文件 7.创建项目所需包和类 1&a…

2024-1.2.12-Android-Studio配置

本地博客: https://k1t0111.github.io/ K1T0 最近在做一些app方向的移动技术开发学习&#xff0c;但是由于AS的配置问题&#xff0c;市面上找不到最新的2024版本的AS的相关配置。笔者也是踩了很多坑&#xff0c;因此想写一篇文章记录一下最新的AS 2024 1.2.12的对应java环境的一…

Html css样式总结

1.Html css样式总结 1.1. 定位position 布局是html中非常重要的一部分&#xff0c;而定位在页面布局中也是使用频率很高的方法&#xff0c;本章节为定位在布局中的使用技巧和注意事项。   position定位有4个属性&#xff0c;分别是static(默认&#xff09;&#xff0c;absol…

CLIP论文中关键信息记录

由于clip论文过长&#xff0c;一直无法完整的阅读该论文&#xff0c;故而抽取论文中的关键信息进行记录。主要记录clip是如何实现的的&#xff08;提出背景、训练数据、设计模式、训练超参数、prompt的作用&#xff09;&#xff0c;clip的能力&#xff08;clip的模型版本、clip…

感知器神经网络

1、原理 感知器是一种前馈人工神经网络&#xff0c;是人工神经网络中的一种典型结构。感知器具有分层结构&#xff0c;信息从输入层进入网络&#xff0c;逐层向前传递至输出层。根据感知器神经元变换函数、隐层数以及权值调整规则的不同&#xff0c;可以形成具有各种功能特点的…

学习笔记 韩顺平 零基础30天学会Java(2024.9.15)

P557 泛型应用实例 P558 泛型使用细节1 P560 泛型使用细节2 P560 泛型课堂练习 代码见Exceise P561 自定义泛型类 对于第二点&#xff0c;因为不知道类型&#xff0c;所以不知道开辟多少空间&#xff0c;因此不能初始化 第三点&#xff0c;静态方法与类相关的&#xff0c;在类…

LeetCode[中等] 189.轮转数组

给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 思路 创建一个新数组&#xff0c;存储原数组旋转后的元素&#xff0c;然后将新数组中的元素复制回原数组。 public class Solution {public void Rotate(int[] nums, int k)…

【docker】阿里云使用docker,2024各种采坑

▒ 目录 ▒ &#x1f6eb; 导读需求开发环境 1️⃣ dial tcp: lookup on 8.8.8.8:53: no such host失败属于DNS问题 2️⃣ docker镜像配置配置最新镜像源 3️⃣ 【重点】阿里云专用获取自己的镜像加速器地址配置镜像地址 &#x1f6ec; 文章小结&#x1f4d6; 参考资料 &#x…

一款强大的吉他乐谱编辑软件GuitarPro 8.2中文解锁版

GuitarPro 8.2中文解锁版是一款强大的吉他乐谱编辑软件&#xff0c;适合新手和专业乐手。它提供详尽教程和实用工具&#xff0c;助力初学者掌握吉他技巧&#xff1b;对于专业乐手&#xff0c;它精准记录音符和节奏&#xff0c;提供丰富编辑功能和音效处理。此外&#xff0c;软件…

虽难必学系列:Netty

Netty 是一个基于 Java 的高性能、异步事件驱动的网络应用框架&#xff0c;广泛用于构建各类网络应用&#xff0c;尤其是在高并发、低延迟场景下表现出色。作为一个开源项目&#xff0c;Netty 提供了丰富的功能&#xff0c;使得开发者可以轻松构建协议服务器和客户端应用程序。…

图像生成领域老牌的GAN模型简要回顾

&#x1f367;背景 这篇文章内容很浅&#xff0c;只是个基础概念介绍&#xff0c;无深度分析。 生成对抗网络&#xff08;Generative Adversarial Networks&#xff0c;简称GAN&#xff09;是一种深度学习模型&#xff0c;由Ian Goodfellow等人在2014年提出&#xff0c;没错&…

【路径规划】全局路径规划算法,基于RRT算法家族的改进

摘要 本项目对经典的 RRT* 算法进行了改进&#xff0c;开发了 Informed-RRT* 算法&#xff0c;用于高效的全局路径规划。Informed-RRT* 通过引入启发式搜索和路径优化策略&#xff0c;在经典 RRT* 的基础上显著提高了路径质量和搜索效率。该算法特别适用于复杂环境中的高维路径…

信号的产生,保存与处理

1.信号的概念&#xff1a; 在生活中的信号&#xff1a;红绿灯&#xff0c;下课铃声&#xff0c;闹钟 红绿灯&#xff0c;你为什么认识红绿灯&#xff1f; 1.能识别红绿灯 2.能理解红灯绿灯黄灯 也就是说信号在还没产生的时候&#xff0c;我们已经认识信号并知道如何去处理…

数据稀缺条件下的时间序列微分:符号回归(Symbolic Regression)方法介绍与Python示例

时间序列概况在日常生活和专业研究中都很常见。简而言之,时间序列概况是一系列连续的数据点 y(0), y(1), …, y(t) ,其中时间 t 的点依赖于时间 t-1 的前一个点(或更早的时间点)。 在许多应用中,研究者致力于预测时间序列概况的未来行为。存在各种建模方法。这些模型通常基于过…

算法:76.最小覆盖子串

题目 链接&#xff1a;leetcode链接 思路分析&#xff08;滑动窗口&#xff09; 还是老样子&#xff0c;连续问题&#xff0c;滑动窗口哈希表 令t用的hash表为hash1&#xff0c;s用的hash表为hash2 利用hash表统计窗口内的个字符出现的个数&#xff0c;与hash1进行比较 选…

Java数据存储结构——平衡二叉树

文章目录 22.1.3 平衡二叉树22.1.3.1 LL22.1.3.2 LR22.1.3.3 RR22.1.3.4 RL 22.1.3 平衡二叉树 平衡二叉树的特点&#xff1a; 二叉树左右两个子树的高度差不超过1任意节点的左右两个子树都是一颗平衡二叉树 在原来的平衡二叉树中&#xff0c;新增数据会破坏平衡性&#xff…

【CMake】使用CMake在Visual Studio 构建多cpp文件项目

首先&#xff0c;我们在 C m a k e Cmake Cmake文件下写入以下代码&#xff1a; #需求的最低cmake程序版本 cmake_minimum_required(VERSION 3.12)#本工程的名字 project(OpenGL)#支持的C版本 set(CMAKE_CXX_STANDARD 20)#本工程主程序文件及输出程序名称&#xff0c;生成exe …