首页/新闻资讯/正文详情

如何用C语言互操作桥接JSVM虚拟机:完整拆解仓颉js_interop系统架构(napi_cffi源码剖析)

发布时间:2026/9/24 16:31:34 来源:云帆数科 栏目:资讯中心
如何用C语言互操作桥接JSVM虚拟机:完整拆解仓颉js_interop系统架构(napi_cffi源码剖析)
如何用C语言互操作桥接JSVM虚拟机完整拆解仓颉js_interop系统架构napi_cffi源码剖析【免费下载链接】cangjie_js_interop项目地址: https://gitcode.com/Cangjie/cangjie_js_interop仓颉/cangjie_js_interop 是一个面向鸿蒙场景的仓颉与 JavaScript 跨语言互操作库它通过C 语言互操作CFFI桥接JSVM JavaScript 虚拟机让仓颉应用可以直接创建 JS 运行时、执行 JS 代码、调用 JS 函数并支持 JS 回调仓颉函数。本文基于源码完整拆解它的napi_cffi 接口层与系统架构帮助新手快速理解跨语言互操作是如何落地的。 先搞懂js_interop 解决什么问题在 OpenHarmony 应用开发中仓颉和 JavaScript 经常需要混合开发仓颉调用 JavaScript复用 JS 丰富的库生态把现成的 JS 模块当作依赖来用JavaScript 回调仓颉在 JS 侧触发高性能的仓颉代码模块发挥仓颉高并发优势。互操作库的核心价值就是在两者之间架起一座桥跨语言传参、跨语言函数调用、跨语言类型转换、跨语言异常处理、引用管理与线程协同全部封装成简洁的 API开发者无需关心底层 C 接口细节。️ 系统架构接口层 框架层 JSVM-API 三层结构图示在 DevEco 中选择 [Cangjie] Empty Ability 模板创建仓颉工程这是使用 js_interop 互操作库的第一步。整体架构分为三层层次组件职责接口层js_interopJSRuntime/JSContext/JSCallInfo/JSCodeCache/JSValue面向开发者的跨语言 API创建运行时、获取上下文、封装 JS 数据对象框架层cangjie_js_interop运行时管理、跨语言函数调用、类型转换、异常处理、引用管理、线程协同接口层能力的真正实现内部全部走 C 互操作调用 JSVMJSVM-APIOH_JSVM_*C 函数JavaScript 虚拟机提供的 C 接口是整条链路的地基几个关键概念对应关系JSRuntime一个 JS 虚拟机实例对应 C 层的JSVM_VM指针JSContext与运行时关联的执行上下文对应JSVM_Env指针保存全局对象模块加载、值访问都发生在它的 Scope 里JSCallInfoJS 回调仓颉方法时的调用信息用来取参数个数与参数列表JSValue跨语言通用货币任何 JS 数据在仓颉侧都用它承载再按需转成JSNumber、JSString、JSBoolean等具体类型。 napi_cffi 源码剖析C 互操作桥如何对接JSVM整个库最底层的桥梁就是 src/napi_cffi.cj 中约 100 个 C 函数的foreign声明块。它的作用可以概括为三件事1️⃣ 把 C 的不透明指针变成仓颉类型在 src/napi_cffi.cj 中JSVM_VM、JSVM_Env、JSVM_Value等类型全部被声明为指向空 C 结构的指针如type JSVM_VM CPointerJSVM_VM__。这种不透明句柄模式意味着仓颉侧完全不解析 JSVM 内部结构只传递指针、按 C ABI 约定调用函数从而天然与 JSVM 二进制兼容。2️⃣ 用C结构体精确复刻 C 的内存布局JSVM_Statussrc/napi_cffi.cj、JSVM_CreateVMOptions、JSVM_Callback等结构体加上C标注后与 C 头文件中的定义逐字段对齐。所有OH_JSVM_*函数统一返回JSVM_Status库内通过check()判断状态码非 OK 就抛出仓颉异常——这就是跨语言异常处理的入口。3️⃣ 覆盖 JSVM 的完整能力面foreign块src/napi_cffi.cj按功能分组声明了虚拟机与上下文生命周期OH_JSVM_Init→OH_JSVM_CreateVM→OH_JSVM_CreateEnv→ 打开/关闭 ScopeJS 值创建与读取OH_JSVM_CreateStringUtf8、OH_JSVM_GetValueInt64等是类型转换的基础脚本编译执行OH_JSVM_CompileScript、OH_JSVM_RunScript、OH_JSVM_CreateCodeCache代码缓存加速二次编译函数调用与回调OH_JSVM_CallFunction、OH_JSVM_CreateFunction、OH_JSVM_GetCbInfo。 跨语言函数调用的双向链路仓颉 → JavaScript调用方向源码在 src/runtime.cj 中可以看到完整流程JSRuntime.create()先执行全局OH_JSVM_Init用Once保证只初始化一次再在 libuv 线程上OH_JSVM_CreateVM创建虚拟机并打开 VM Scope随后 src/runtime.cj 的mainContext属性通过OH_JSVM_CreateEnv创建环境包装成JSContext。之后在上下文 Scope 中evaluateJS 代码、从全局对象取出 JS 函数、CallFunction调用返回值以JSValue回到仓颉侧。JavaScript → 仓颉回调方向关键在 src/function.cj 的jsFunctionCallbackStub这是一个 C 函数指针通过OH_JSVM_CreateFunction注册给 JSVM。当 JS 侧调用该函数时JSVM 反向调用这个 stub它再做四步由env反查对应的JSContext通过JSCallInfo.parseCallInfosrc/function.cj把 C 侧的JSVM_CallbackInfo解析成参数数组按lambdaId找到预先注册的仓颉闭包JSLambda并执行若仓颉侧抛异常throwExceptionToJSsrc/function.cj把它转成 JS 异常向 JS 侧传播——双向异常处理由此闭环。线程协同仓颉线程默认不绑定系统线程而 JSVM 要求操作必须发生在绑定线程上。库内部用 src/uv.cj 的UvLoop封装 libuv 事件循环JSContext在访问env前会检查当前线程src/context.cj异步任务则通过postTask投递回 JS 线程执行保证句柄安全。 快速上手3 步跑通第一次互操作创建仓颉工程在 DevEco 中选择[Cangjie] Empty Ability模板仓库可通过git clone https://gitcode.com/Cangjie/cangjie_js_interop获取源码并放入工程顶层目录添加依赖把互操作库加入cjpm.toml的依赖项如下图编写调用代码新建仓颉文件后按 doc/js_interop_user_manual.md 的示例JSRuntime.create()建运行时 →runtime.mainContext取上下文 →context.evaluate(...)加载 JS →context.global[addNumber].asFunction()取函数 →globalCall([1, 2])调用并取回结果。完整 API 细节可查阅 doc/js_interop_api_docs.md。运行效果示意按钮点击触发仓颉函数内部完成仓颉→JS 互操作调用 源码导读各模块文件分工模块文件行数职责src/napi_cffi.cj634C 互操作接口定义JSVM 类型、结构体、foreign 函数声明src/runtime.cj177JSRuntimeVM 创建、销毁、堆统计、状态码检查src/context.cj392JSContextScope 管理、异步任务、引用回收、全局对象访问src/value.cj405JSValue及 JS 基础类型Boolean/Number/String封装src/function.cj194JS 函数调用与仓颉回调 stub、跨语言异常转换src/script.cj152JSScript/JSScriptBuilder脚本编译、代码缓存src/uv.cj242libuv 事件循环封装跨语言线程协同的核心src/slab.cj185小对象内存池承载仓颉闭包与异步回调辅助模块还包括 src/string.cj、src/array.cj、src/map.cj、src/object.cj对应 JSString/JSArray/JSMap/JSObject 类型以及 src/heap.cj、src/log.cj。❓ 常见问题FAQQ1napi_cffi.cj 和 Node.js 的 N-API 是一回事吗命名上借鉴了 N-API 的设计思想C 语言函数指针 不透明句柄但对接的是 JSVM 的OH_JSVM_*C 接口不是 Node 的 N-API。Q2为什么仓颉侧拿不到 JSVM 的内部结构这是刻意为之。C空结构 指针的不透明设计让仓颉侧与 JSVM 实现完全解耦JSVM 升级时只要 C ABI 不变互操作库就无需修改。Q3目前支持哪些平台和方向当前仅支持 Linux 平台编译cjpm build --release运行时面向鸿蒙场景调用方向支持仓颉调用 JS 后 JS 回调仓颉编译配置见根目录 cjpm.toml。Q4JS 侧异常会导致仓颉崩溃吗不会。状态码检查checkAndHandleError会把挂起的 JS 异常取出并转换为仓颉Exception反方向则由throwExceptionToJS把仓颉异常包装为 JS Error两侧都有兜底。✅ 总结仓颉/cangjie_js_interop 用三层架构把跨语言调用的复杂性层层收敛napi_cffi.cj 的 C 互操作声明对接 JSVM框架层实现函数调用、类型转换、异常与引用管理接口层则只暴露JSRuntime/JSContext/JSValue等寥寥几个类。理解了这条C 指针 → CFFI → 仓颉对象的链路你就掌握了整个互操作库的骨架后续阅读任意模块源码都会事半功倍。【免费下载链接】cangjie_js_interop项目地址: https://gitcode.com/Cangjie/cangjie_js_interop创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

Kornia 边界框对象式 API 深度指南:Boxes 与 Boxes3D 的格式转换、几何变换与掩码生成
Kornia 边界框对象式 API 深度指南:Boxes 与 Boxes3D 的格式转换、几何变换与掩码生成

计算机视觉人工智能深度学习图像处理 【免费下载链接】kornia 🐍 Geometric Computer Vision Library for Spatial AI 项目地址: https://gitcode.com/gh_mirrors/ko/kornia 点击查看 免费下载 导读:本文围绕 Kornia 的 kornia.geometry.box… · 2026/9/24 16:31:34

palera1n:A8 到 A11 设备 iOS 15 越狱的 checkm8 完整指南
palera1n:A8 到 A11 设备 iOS 15 越狱的 checkm8 完整指南

palera1n:A8 到 A11 设备 iOS 15 越狱的 checkm8 完整指南 【免费下载链接】palera1n Jailbreak for A8 through A11, T2 devices, on iOS/iPadOS/tvOS 15.0, bridgeOS 5.0 and higher. 项目地址: https://gitcode.com/GitHub_Trending/pa/palera1n palera1n… · 2026/9/24 16:31:25

Flink CDC 安装指南:三步部署加一份最小 YAML,把实时数据同步真正跑起来
Flink CDC 安装指南:三步部署加一份最小 YAML,把实时数据同步真正跑起来

Flink CDC 安装指南:三步部署加一份最小 YAML,把实时数据同步真正跑起来 【免费下载链接】flink-cdc Flink CDC is a streaming data integration tool 项目地址: https://gitcode.com/GitHub_Trending/flin/flink-cdc 数据库一有变更&#xff0c… · 2026/9/24 16:31:10

基于SpringBoot+Vue的美妆产品推荐系统(源代码+文档+PPT+调试+讲解)
基于SpringBoot+Vue的美妆产品推荐系统(源代码+文档+PPT+调试+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台… · 2026/9/24 17:03:47

openFrameworks 视频播放实战:基于 ofVideoPlayer 的加载、速度控制与像素可视化
openFrameworks 视频播放实战:基于 ofVideoPlayer 的加载、速度控制与像素可视化

openFrameworks 视频播放实战:基于 ofVideoPlayer 的加载、速度控制与像素可视化 【免费下载链接】openFrameworks openFrameworks is a community-developed cross platform toolkit for creative coding in C. 项目地址: https://gitcode.com/gh_mirrors/op/ope… · 2026/9/24 17:03:47

30 分钟配好 Continue:JetBrains 插件安装、离线构建与调参指南
30 分钟配好 Continue:JetBrains 插件安装、离线构建与调参指南

30 分钟配好 Continue:JetBrains 插件安装、离线构建与调参指南 【免费下载链接】continue open-source coding agent 项目地址: https://gitcode.com/GitHub_Trending/co/continue 写代码时总要切到网页版 AI 问一句,答完再切回来贴代码&#xf… · 2026/9/24 17:03:47

【Dify】FLUX绘画机器人多模态识别与语音交互自动化
【Dify】FLUX绘画机器人多模态识别与语音交互自动化

以多模态智能交互为核心的自动化创作方式,正推动AI艺术、教育与硬件结合的快速发展。视觉识别、语音播报与机器人控制的结合,为传统绘画和教学带来了新的可能。 本文梳理FLUX绘画机器人结合多模态识别和语音播报的完整工作流,实现从图片输入、内容识别、创意生成到语音解读… · 2026/9/24 17:03:27

国军标B码闰秒的测试方法
国军标B码闰秒的测试方法

此图来自成都云智优创科技有限公司www.iyzyc.cn简介GJB-B码发生器测试仪是专门用于产生B码的测试仪,借助它可以用来测试带B码对时的接收设备。通过配置软件,可以输出为任意时间,特别是对临界时间的测试,比如2099年12月31日23时59分… · 2026/9/24 17:03:27

大麦自动抢票指南:Python Selenium + Appium 双端抢票脚本完整教程
大麦自动抢票指南:Python Selenium + Appium 双端抢票脚本完整教程

大麦自动抢票指南:Python Selenium Appium 双端抢票脚本完整教程 【免费下载链接】ticket-purchase 大麦自动抢票,支持人员、城市、日期场次、价格选择 项目地址: https://gitcode.com/GitHub_Trending/ti/ticket-purchase ticket-purchase 是一… · 2026/9/24 17:02:56

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码