架构
一个 C ABI 内核(DarraAI.Core,契约头 darra_ai.h)是唯一核。六种语言是薄壳:只翻译类型和错误码,不写密码学、不写容器格式、不另造「模型组 / 全局引擎」。同一 bug 只允许在 Core 修一次。
SDK 可选。开放导出接到任意框架的路径不经过本图。本页描述的是走 SDK 时的分层。
相关:SDK 介绍 · 运行时 Provider · C SDK
分层
应用(任选其一,同级,互不引用)
AI Studio GUI — 引用 C# 绑定 + authoring 构建(加密/签发/指纹扰动)
PLC Vision Runtime — 引用 C# 绑定 + runtime 构建(只解密/推理)
客户应用 — 任选一种语言绑定 + runtime 构建
│
▼ 全部推理入口:open → infer → close
语言薄壳(零密码学)
C / C++ 头 C# P/Invoke Python cffi Java JNI Rust FFI
│
▼
DarraAI.Core(native,C ABI,C++17 / CMake) ← 唯一真相
crypto DARM1 解码 / DARMK2 验票 / AES-GCM / HKDF
session PayloadKind 分发 → Provider
memory 明文窗口最小化;用完清零
diag darra_diag_collect
runtime darra_runtime_ensure
│
▼ dlopen / LoadLibrary(sha256 白名单,禁任意路径)
Provider 细包(按需下载,不进内核)
onnx-cpu / onnx-cuda / onnx-openvino / onnx-trt-ep / onnx-directml
trt-native / paddle-cpu / edge-rknn(仅 linux-arm64)
箭头只从上往下:Provider 依赖 Core ABI,Core 不依赖任何 Provider;绑定依赖 C ABI,Core 不依赖绑定。
C ABI 唯一核
- 只导出 C 函数 + 不透明句柄(
darra_session*)+ 定长结构体。永不导出 C++ 类 / STL。 - 结构体首字段
uint32_t size,调用方填sizeof(...)。SDK 只读写它认识的字段,旧头配新库照常工作。 - 新增函数只追加、不改旧签名。major 变 = ABI 破坏。
- 字符串 UTF-8。堆字符串用
darra_string_free释放;禁止free/delete[](Windows 上可能不是同一 CRT 堆)。darra_version_string是静态串,禁止释放。 - 返回值:除注明
void的以外一律int32_t,0=DARRA_OK。失败后同一线程立刻darra_last_error。参数契约违反归DARRA_INTERNAL,message 指明哪个参数;非法入参下不允许崩溃。
构建风味:
| 风味 | 给谁 | 有什么 |
|---|---|---|
| runtime | 客户机 / PLC / 板卡 | 解密、验票、推理、诊断、包管理。strings 不得出现 darra_encrypt_ / darra_issue_ / darra_fingerprint_perturb |
| authoring | 仅随 AI Studio 安装包 | 额外三个符号:加密、签发、权重扰动。不进公开 SDK 包 |
darra_version_string():公开包 1.0.0+runtime,Studio 本机 1.0.0+authoring。
六语言薄壳
| 语言 | 形态 | 目标 |
|---|---|---|
| C | darra_ai.h + import lib + dll/so | MSVC / GCC / Clang,C11+ |
| C++ | 同一头,extern "C" | 不另包一层 C++ 类库 |
| C# | NuGet Darra.AI.Runtime,P/Invoke,native 按 rid 内嵌 | net8.0 |
| Python | darra-ai wheel,cffi 只走 ABI 模式(ffi.dlopen) | py3.10–3.13 |
| Java | Maven xyz.darra:darra-ai,JNI,natives 按 classifier | JDK 17+ |
| Rust | crate darra-ai + darra-ai-sys | stable |
用户只装一个语言包。内核 native 绑在包里。重依赖全部在 Provider 包,见 运行时 Provider。
绑定里重写容器 / 授权逻辑 = 删,去 Core 修。
会话:open → infer → close
一个 darra_session* = 一份已加载模型 + 一个 Provider。多模型 = 多会话;同模型要第二份实例 = 再开一个会话。没有「模型组 / 全局引擎」入口。
open / open_plain / *_ex
│ 读容器头或明文探测 → 选 Provider → 必要时内部 ensure
│ 验票 / 解密(明文路径跳过)
▼
反复 infer_image ← 每帧走这里,不要每张图重新 open
│ 阻塞调用;不承诺硬实时
▼
close ← 释放;明文窗口清零。之后句柄失效
| 函数 | 作用 |
|---|---|
darra_session_open / open_ex | 打开 .darmodel(DARM1)。密码与 .darmkey 至少给一个;都给则 key 优先 |
darra_session_open_plain / open_plain_ex | 打开明文 .onnx / .pdmodel(伴生 .pdiparams)或含二者的目录。同一推理路径,跳过解码与验票。.pt / .pth 拒载 |
darra_session_infer_image | 一张静止图像 → JSON 结果。v1 不做视频流;连续帧循环调用 |
darra_session_meta_json | 容器头的派生视图(camelCase)。缺字段为 null / 缺席,不编 640/80/17 |
darra_session_close | 释放。NULL 安全。禁止与在飞调用并发 |
open* 按 PayloadKind × 硬件 × prefer_provider 选 Provider;包未装则内部 darra_runtime_ensure 一次(无进度回调,可能阻塞下载)。指名 Provider 不可用 = fail-closed,绝不静默换别的 Provider 冒充成功。想看进度请先自己调 ensure(幂等)。
线程:
- 不同会话互不干扰,可并发。
- 同一会话的
infer_image允许多线程并发,但吞吐扩展推荐每线程一个会话。 intra_op_threads/inter_op_threads:0= 自动,自动上限min(硬件逻辑核, 4)。cpu_affinity_mask:0= 不设。- 禁止改 Windows
ReservedCpuSets,禁止动 PLC 隔离核。选项只约束本会话线程池。
图像由调用方传入宽、高、步长、通道和像素指针。阈值、输入边长、类别名在出包时写入容器头,推理侧不让改。
导出格式即加载格式
Studio 写出的 DARM1 header_json 就是运行时读的那份。加载方零配置,不存在「打开后再喂宽高 / 类别 / 均值」。字段表见 模型元数据。
与开放导出的关系
Studio 可以不加密、不签发,直接导出明文载荷。那条路:
- 不经过
darra_session_* - 不经过 Provider 清单
- 接到 ORT / TensorRT / OpenVINO / 任何能读该格式的框架
加密容器没有第二条消费路径:要跑 .darmodel,必须走本 SDK 的 open → infer → close。公开 runtime 包不能把明文再打成 DARM1。
平台
| Windows x64 | Linux x64 | Linux ARM64(RK3588) | macOS | |
|---|---|---|---|---|
| Core runtime | 有 | 有 | 有 | v1 不做 |
加密 .darmodel | 有 | 有 | 有 | — |
edge-rknn | 不存在此包 | 不存在此包 | 有 | — |
诊断 JSON 不含密钥 / 密码 / token / 机器指纹字节。darra_diag_collect 可能打到数百毫秒,禁止放在 PLC 扫描周期上。