如何用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:39 阅读更多 →
使用 AWS SDK for C++ 调用 AWS STS:AssumeRole 临时凭证示例详解

使用 AWS SDK for C++ 调用 AWS STS:AssumeRole 临时凭证示例详解

使用 AWS SDK for C 调用 AWS STS:AssumeRole 临时凭证示例详解 【免费下载链接】aws-doc-sdk-examples Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For…

2026/9/24 16:31:39 阅读更多 →
使用 prisma-binding 构建基于 Prisma 服务的 GraphQL 服务器

使用 prisma-binding 构建基于 Prisma 服务的 GraphQL 服务器

使用 prisma-binding 构建基于 Prisma 服务的 GraphQL 服务器 【免费下载链接】prisma1 💾 Database Tools incl. ORM, Migrations and Admin UI (Postgres, MySQL & MongoDB) [deprecated] 项目地址: https://gitcode.com/gh_mirrors/pr/prisma1 导读 …

2026/9/24 16:30:34 阅读更多 →

最新新闻

Ekko Studio docx Skill 源码级解析:Word 修订(Tracked Changes)与批注(Comments)的 WordprocessingML 处理

Ekko Studio docx Skill 源码级解析:Word 修订(Tracked Changes)与批注(Comments)的 WordprocessingML 处理

AI 应用人工智能AI Agent本地部署前端后端工作流自动化 【免费下载链接】ekko-studio Ekko Studio is a local-first AI workspace for multi-agent chat, coding, and visual workflows, available on desktop and the web. 项目地址: https://gitcode.com/gh_mirr…

2026/9/24 22:02:05 阅读更多 →
Java Swing 黄金矿工小游戏:抓钩状态机与碰撞检测实战

Java Swing 黄金矿工小游戏:抓钩状态机与碰撞检测实战

简介:这是一份基于Java实现的黄金矿工小游戏完整源码包,面向Java初学者、课程设计学生以及想通过经典小游戏练手的开发者,帮助读者理解Swing图形界面、游戏循环、碰撞检测与资源加载等核心机制。压缩包共30个文件,约141KB&#xf…

2026/9/24 22:02:05 阅读更多 →
体育馆场地预约系统开发实战:微信小程序+Django+Flask架构解析

体育馆场地预约系统开发实战:微信小程序+Django+Flask架构解析

体育馆场地预约平台开发手记:从电话排队到小程序一键订场做体育馆场地预约系统,最早是因为一个朋友在高校体育部上班,天天被电话轰炸:羽毛球场地有没有?今晚七点的场子被人占了能不能调?隔壁单位想包场怎么…

2026/9/24 22:02:05 阅读更多 →
GPT-Live-1+Agora构建AI会议助手实战指南

GPT-Live-1+Agora构建AI会议助手实战指南

1. 这不是“又一个AI聊天框”,而是一个能真正坐在会议室里干活的数字同事GPT‑Live‑1 Agora 实战教程:做一个能参会、操作看板的 AI 助手——这个标题里藏着三个被多数人忽略的关键动作:“能参会”、“操作看板”、“实战教程”。它不讲大模…

2026/9/24 22:02:05 阅读更多 →
全栈AI修图Agent实战:从架构设计到模型调度与踩坑记录

全栈AI修图Agent实战:从架构设计到模型调度与踩坑记录

“又一个新项目完结”——这句话说出口的时候,我终于能把“全栈 AI 修图 Agent”从待办列表里划掉了。这个项目从立项到交付,前后差不多一个多月,期间推翻过一版架构,也踩了不少模型和前后端的坑。如果你最近也在折腾 AI 全栈项目…

2026/9/24 22:02:05 阅读更多 →
如何挑选靠谱的AI创业项目机构?资源评估与避坑实操指南

如何挑选靠谱的AI创业项目机构?资源评估与避坑实操指南

想找靠谱的AI人工智能创业项目机构,我建议你先把“找机构”这三个字放一放。过去两年我陪不少团队聊过孵化器、加速器、产业平台,见过真给资源的,也见过把“AI”当挂件的。这篇文章不吹不黑,聊聊什么样的AI创业机构值得进、怎么判…

2026/9/24 22:01:05 阅读更多 →

日新闻

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

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

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

2026/9/24 0:00:19 阅读更多 →
单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:19 阅读更多 →
C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/24 0:00:19 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →