news 2026/9/3 0:50:12

一个 C Core,同时被 JNI 和 dart:ffi 调用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一个 C Core,同时被 JNI 和 dart:ffi 调用

——从 0 设计一套“可跨语言复用”的 native 核心库

关键词:FFI / JNI / dart:ffi / C Core / 系统边界 / 句柄模型 / 架构设计

一、这篇文章我们到底要验证什么?

不是验证:

  • JNI 会不会写

  • dart:ffi 会不会用

而是验证一件更重要的事:

👉你能不能写出一个“独立于语言存在”的 native core。

也就是这种能力:

任何上层语言 (Java / Kotlin / Dart / Swift / Python) ↓ 语言绑定层 ↓ 统一 Native Core

如果一个 core:

  • 只能给 JNI 用
  • 一换语言就推倒重来

那它本质还是“项目代码”,不是“系统资产”。

二、整体架构设计(先定型,再写代码)

我们先给这次实战定一个系统级结构

ffi-core/ ├── core/ # 纯 C 核心(系统资产) │ ├── include/ │ │ └── core_api.h # 唯一对外接口 │ └── src/ │ └── core.c │ ├── android-jni/ # JVM 绑定层 │ ├── CMakeLists.txt │ └── jni_bridge.c │ ├── flutter-ffi/ # Dart 绑定层 │ ├── lib/ │ │ └── core_ffi.dart │ └── android/ / ios/

👉 核心原则:

  • core 层不认识 JNI / Dart / Flutter
  • 绑定层只做翻译,不写业务
  • 接口以C ABI 为唯一标准

三、核心设计:先写“系统接口”,再写实现

✅ 1. 我们要一个最小但完整的系统模型

我们设计一个非常典型的系统级模型:

👉 一个 native 对象 + 生命周期 + 行为函数

比如:一个计数器引擎(只是模型,不是玩具)

它具备:

  • 创建 / 销毁
  • 状态维护
  • 行为调用

✅ 2. 纯 C 接口(core_api.h)

#ifndef CORE_API_H #define CORE_API_H #ifdef __cplusplus extern "C" { #endif typedef void* CoreHandle; // 生命周期 CoreHandle core_create(int init_value); void core_destroy(CoreHandle handle); // 行为 int core_add(CoreHandle handle, int delta); int core_get(CoreHandle handle); #ifdef __cplusplus } #endif #endif

这里有几个系统工程级关键点:

✔ 使用 void* 作为 opaque handle
✔ 不暴露 struct
✔ 明确 create / destroy
✔ 不依赖任何上层语言
✔ 完全 C ABI

👉 这一层,决定了你是不是“系统设计者”。

✅ 3. native 实现(core.c)

#include "core_api.h" #include <stdlib.h> typedef struct { int value; } Core; CoreHandle core_create(int init_value) { Core* c = (Core*)malloc(sizeof(Core)); c->value = init_value; return (CoreHandle)c; } void core_destroy(CoreHandle handle) { if (!handle) return; free(handle); } int core_add(CoreHandle handle, int delta) { Core* c = (Core*)handle; c->value += delta; return c->value; } int core_get(CoreHandle handle) { Core* c = (Core*)handle; return c->value; }

👉 到此为止,你已经完成了:

一套真正“跨语言系统核心”的设计。

后面所有语言,只是外壳

四、Android JNI 层:证明 JVM 能用它

1️⃣ JNI 只做“翻译层”

#include <jni.h> #include "core_api.h" JNIEXPORT jlong JNICALL Java_com_demo_CoreNative_create(JNIEnv* env, jobject thiz, jint v) { return (jlong) core_create(v); } JNIEXPORT void JNICALL Java_com_demo_CoreNative_destroy(JNIEnv* env, jobject thiz, jlong handle) { core_destroy((CoreHandle)handle); } JNIEXPORT jint JNICALL Java_com_demo_CoreNative_add(JNIEnv* env, jobject thiz, jlong handle, jint d) { return core_add((CoreHandle)handle, d); } JNIEXPORT jint JNICALL Java_com_demo_CoreNative_get(JNIEnv* env, jobject thiz, jlong handle) { return core_get((CoreHandle)handle); }

Java 层:

class CoreNative { native long create(int v); native void destroy(long h); native int add(long h, int d); native int get(long h); }

👉 注意:
Java 世界没有“对象”,只有long 句柄

这一步完成后,你已经验证:

✅ JVM ↔ native core 跑通
✅ 句柄模型可用
✅ 生命周期清晰

五、Flutter dart:ffi 层:证明 Dart 也能用它

1️⃣ Dart 侧函数映射

typedef _core_create_c = Pointer<Void> Function(Int32); typedef _core_create_d = Pointer<Void> Function(int); typedef _core_add_c = Int32 Function(Pointer<Void>, Int32); typedef _core_add_d = int Function(Pointer<Void>, int);

加载动态库:

final lib = DynamicLibrary.open("libcore.so"); final coreCreate = lib.lookupFunction<_core_create_c, _core_create_d>("core_create"); final coreAdd = lib.lookupFunction<_core_add_c, _core_add_d>("core_add");

调用:

final handle = coreCreate(10); final v = coreAdd(handle, 5);

👉 这里你会清楚地看到:

Dart 不是在“调 Flutter”,
而是在直接进入 native 世界。

六、到这一刻,你已经完成了一次系统级验证

你现在手里已经有了:

  • 一套独立 C Core
  • 一套 JVM 绑定
  • 一套 Dart 绑定

而且:

  • core 层没有任何语言痕迹
  • 两种运行时同时可用
  • 生命周期模型统一

👉 这就是跨语言系统核心库的标准形态

七、这一步真正训练的是什么能力?

不是 JNI。
不是 dart:ffi。

而是:

✅ 系统接口设计能力
✅ 语言边界抽象能力
✅ 生命周期建模能力
✅ 多运行时适配能力
✅ “核心下沉”的架构能力

这正是:

  • Framework
  • 引擎
  • 机器人中间层
  • 跨平台 SDK

最核心的能力。

八、为什么一定要两个都调 native?

因为第二个调用方会强制你:

  • 接口必须纯

  • 生命周期必须干净

  • 数据模型必须稳定

👉 第二个语言,本质是架构压力测试器

最后一篇:

从 FFI 到系统架构:跨语言核心库的设计方法

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/2 16:03:56

Deepoc具身模型开发板:无人机智能化的技术底座与生态价值

引言&#xff1a;从"飞行相机"到"空中智能体"的范式革命在无人机的发展历程中&#xff0c;我们经历了从"遥控玩具"到"程序化执行"的阶段&#xff0c;但始终未能突破"智能缺位"的瓶颈。传统无人机虽然能够完成预设航线飞行、…

作者头像 李华
网站建设 2026/9/2 23:56:11

从零到一搞定论文:6款免费AI生成器实操指南,精准控制AI率无压力

一、论文写作的「AI工具选型速查表」&#xff1a;先选对工具&#xff0c;再高效写作 作为经常帮学弟学妹改论文的“过来人”&#xff0c;我发现90%的论文焦虑都源于“用错工具”——要么生成的内容太像AI&#xff0c;要么格式混乱&#xff0c;要么文献引用不规范。为了帮你快速…

作者头像 李华
网站建设 2026/9/2 22:25:04

信息安全——Secure Hardware Extensions (SHE) 之 < SHE是谁? >

安全硬件扩展 (SHE) &#xff1a; Secure Hardware Extensions1. SHE介绍安全硬件扩展&#xff08;SHE&#xff09;是针对任何给定微控制器的片上扩展&#xff0c;是一种硬件安全模块。其目的是将对加密密钥的控制从软件领域转移到硬件领域&#xff0c;从而保护这些密钥免受软件…

作者头像 李华
网站建设 2026/9/2 21:37:13

关于MIO设置JTAG模式,还可以从Flash启动说明

一、说明 硬件设计为JTAG模式”&#xff0c;实际上是指通过MIO引脚将 BOOT_MODE[3:0] 配置为了 0011 或 1011&#xff0c;这个模式更准确地称为“JTAG 优先”模式&#xff0c;而不是“JTAG 唯一”模式。在这个模式下&#xff0c;ZYNQ的启动过程会首先尝试从JTAG启动&#xff0c…

作者头像 李华
网站建设 2026/9/2 21:38:12

颠覆测试认知:AI如何透视软件测试的黑暗角落

第一章 测试盲区&#xff1a;隐匿的质量黑洞 1.1 盲区的致命伪装 认知陷阱案例&#xff1a;某金融APP在压力测试中通过率100%&#xff0c;上线后却因除夕红包雨导致数据库死锁 传统覆盖率的欺骗性&#xff1a;某医疗系统代码覆盖率达95%&#xff0c;仍遗漏了罕见病编码组合的…

作者头像 李华
网站建设 2026/9/2 23:59:18

云服务器2G内存运行MySQL 9.0有哪些性能瓶颈?如何调优?

我手上有台2G内存云服务器。 装了宝塔面板&#xff0c;顺手跑了 MySQL 9.0.1。 之前还有人说2G内存的服务器不能安装MySQL 8.0。 能跑&#xff0c;没错。 一般小项目还是完全够用的&#xff0c;但如果网站访问量升高&#xff0c;数据量增加&#xff0c;MySQL 就可能“喘粗气…

作者头像 李华