跳到主要内容

Rust SDK 概述

Darra AI SDK 的 Rust 绑定。工作区两个 crate:只翻译 C ABI 的类型和错误码,零密码学、零容器格式逻辑。契约权威 = Core/include/darra_ai.h

crate职责
darra-ai-sys手写 extern "C"(不用 bindgen)+ build.rsDARRA_AI_CORE_LIB_DIR 找库
darra-ai安全封装:Session / Error / runtime / diagnostics / authoring

同一 bug 只允许在 Core 修一次。

crate 名与库名
  • crate 名Cargo.toml 依赖):darra-ai
  • 库名(代码里 use):darra_ai,例如 use darra_ai::{ImageDesc, Session};

工作区 publish = falseversion = "1.0.0"rust-version = "1.70"

安装

本绑定不发布 crates.io。以路径依赖接入:

[dependencies]
darra-ai = { path = "A:/c/Darra/Darra_AI_Studio/Darra.AI.Studio.SDK/Rust/darra-ai" }

签发三个函数再加 features = ["authoring"](见下方 authoring)。

构建必须设置 DARRA_AI_CORE_LIB_DIR,指向 Core 链接库目录(找不到会 panic 中文 hint):

$env:DARRA_AI_CORE_LIB_DIR = 'A:\c\Darra\Darra_AI_Studio\Darra.AI.Studio.SDK\Core\out\build\windows-x64-debug\lib\Debug'
cd A:\c\Darra\Darra_AI_Studio\Darra.AI.Studio.SDK\Rust
cargo check

Windows 该目录需含 darraai_core.libDarraAI.Core.lib;Linux 需含 libdarraai_core.sobuild.rs 还认 libDarraAI.Core.so / darraai_core.so)。运行时还要把对应的 .dll / .so 放到 PATH 或可执行文件旁。

环境要求

项目要求
操作系统Windows 或 Linux(build.rsCARGO_CFG_TARGET_OS.lib / .so
Rust1.70+(stable,工作区 rust-version
Core已编出的 darraai_core 链接库;ABI major 必须为 1

加载后 open / ensure / collect 等入口会核对 darra_version 的 major == DARRA_VERSION_MAJOR(1),不等立即失败。

快速开始

推荐顺序
  1. diagnostics::collect 导出本机诊断(可选,禁止放进 PLC 扫描周期)
  2. runtime::ensure(None, None, …) 按硬件自动选 Provider 包(幂等)
  3. Session::open 打开 .darmodel,或 Session::open_plain 打开明文 .onnx
  4. infer_image 推理;Session 离开作用域时 Dropdarra_session_close
use darra_ai::{ImageDesc, Session};
use darra_ai::{diagnostics, runtime};

fn main() -> Result<(), darra_ai::Error> {
let packed = darra_ai::version();
if darra_ai::version_major(packed) != 1 {
return Err(darra_ai::Error::Internal {
message: format!("ABI 不匹配,库版本 = {}", darra_ai::version_string()),
hint: "Darra.AI SDK 与 DarraAI.Core 升到同一发布批次后重试。".to_string(),
});
}

let _ = diagnostics::collect();

runtime::ensure(None, None, Some(&|percent, stage| {
eprint!("\r环境准备 [{stage:<8}] {percent:5.1}% ");
}))?;

let session = Session::open("model.darmodel", Some("model.darmkey"), None, None)?;
eprintln!("[meta] {}", session.meta()?);

let jpeg = std::fs::read("photo.jpg").map_err(|e| darra_ai::Error::IoNotFound {
message: format!("读图片失败:photo.jpg ({e})"),
hint: String::new(),
})?;
let json = session.infer_image(&jpeg, &ImageDesc::auto())?;
println!("{json}");
Ok(())
}

明文 ONNX:Session::open_plain("model.onnx", None)。绑定注释:训练格式(.pt / .pth / Paddle)收到即 UnsupportedPayload

工业相机裸缓冲 BGR888(禁止 ImageDesc::auto(),嗅探不出通道序;stride = 0 表示紧凑 = width × 3):

let desc = ImageDesc::bgr888(1920, 1080, 0);
let json = session.infer_image(&frame, &desc)?;

完整脚本见 darra-ai/examples/infer.rs

cargo run -p darra-ai --example infer -- model.darmodel photo.jpg model.darmkey
cargo run -p darra-ai --example infer -- model.onnx photo.jpg

设计理念

  • 薄绑定 — 类型 / 错误码翻译,容器解码与验票全在 Core
  • RAIISession 不可 CloneDropdarra_session_close(NULL 安全由 Core 保证)
  • Result<T, Error> — 失败变体与 darra_error_code 1..=18 逐码对应;未知新码走 Error::Unknown
  • 安全 API — 用户侧无需 unsafe;FFI 封在 darra-ai-sys 与本 crate 内部
  • ABI 门 — 入口 ensure_abi():major 不等禁止继续

功能特性

功能API
版本version() 打包 (major<<16)|(minor<<8)|patchversion_string() 形如 "1.0.0+runtime" / "1.0.0+authoring"(静态,禁止释放);version_major(packed)
加密容器会话Session::open(path, key_path, password, prefer_provider)key_pathpassword 至少给一个,都给则 key 文件优先验票
可扩展入口Session::open_ex(path, &SessionOptions)当前翻译到 darra_session_open 四参SessionOptions 只有 key_path / password / prefer_provider,没有 Core 的 intra/inter 线程字段)
明文 ONNXSession::open_plain(onnx_path, prefer_provider)
元信息meta() UTF-8 JSON;feature jsonmeta_json()serde_json::Value
只读属性task / labels / input_width / input_height / channels / layout / payload_kind / provider_id / encrypted,全部从 meta JSON 派生
推理infer_image(&[u8], &ImageDesc);feature jsoninfer_image_json。v1 单张图像,不承诺硬实时
图像描述ImageDesc::auto() / rgb888(w,h,stride) / bgr888(w,h,stride)ImageFormat::{Auto, Encoded, Rgb888, Bgr888}
Provider 包runtime::ensure(profile, offline_zip, progress)runtime::cancel()
环境自检diagnostics::collect();feature jsoncollect_json()
签发(feature authoringencrypt_onnx / issue_key / fingerprint_perturb

prefer_providerNone 时按载荷 × 硬件 × 已装包自动选;指名但不可用 = fail-closed,绝不静默降级

快速示例:

use darra_ai::{ImageDesc, ImageFormat, Session, SessionOptions};

let session = Session::open_ex(
"model.darmodel",
&SessionOptions::new()
.key_path("model.darmkey")
.prefer_provider("onnx-cpu"),
)?;

let _ = session.task()?; // Some("detect") 或 None
let _ = session.provider_id()?; // 实际选中的 Provider,不是 prefer 入参
let _ = session.encrypted()?; // 明文 ONNX 为 false

let encoded = ImageDesc {
format: ImageFormat::Encoded,
width: 0,
height: 0,
stride: 0,
};
let _ = session.infer_image(&jpeg, &encoded)?;

进度回调 (percent 0..100, stage),stage ∈ probe / manifest / download / verify / install / done。回调在 SDK 内部工作线程触发,回调里禁止再调任何 darra APIensure 的 trampoline 已挡住 panic 穿过 FFI)。cancel 可从任意线程调(含 UI);进度回调内部禁止调用

Cargo feature

feature默认作用
jsonserde_jsonSession::infer_image_json / meta_json / diagnostics::collect_json
authoring三个签发函数,连带打开 darra-ai-sys/authoring

authoring:必须链接 authoring 版 Core

encrypt_onnx / issue_key / fingerprint_perturb 只在 Core 的 authoring 构建DARRA_AUTHORING=ON)里有符号。runtime 构建物理上没有 darra_encrypt_ / darra_issue_ / darra_fingerprint_ 前缀,链接 runtime 再调用 = 链接/加载失败(物理隔离,不是权限开关)。

darra-ai = { path = "...", features = ["authoring"] }

调用顺序:fingerprint_perturbencrypt_onnxissue_key。扰动必须发生在加密前。

use darra_ai::authoring::{self, KeyOptions};

authoring::fingerprint_perturb("in.onnx", "perturbed.onnx", customer_seed)?;
authoring::encrypt_onnx("perturbed.onnx", "model.darmodel")?;
authoring::issue_key(
"model.darmodel",
Some("password"),
"model.darmkey",
Some(&KeyOptions::permanent()), // bind_machine=false, trial_runs=0
)?;

KeyOptions { bind_machine, trial_runs }bind_machine=true 绑定签发时的机器指纹;trial_runs>0 为试用计次。passwordNone = 本授权不启用密码通道。密码无法事后找回,官方不解回明文。本模块零密码学:只转发 C ABI。

线程安全(头文件 §6)

  • 不同会话可并发(Session: Send)。
  • 同一会话 infer_image 可多线程并发(Session: Sync);吞吐扩展仍推荐每线程一个会话。
  • closeDrop)禁止与在飞调用并发——安全 Rust 借用 / Arc 规则保证。
  • diagnostics::collect 耗时可到数百毫秒(WMI / NVML / sysfs),禁止在 PLC 扫描周期调用
  • runtime::ensure 进程内互斥串行,重复/并发安全。

错误处理

失败返回 darra_ai::Error。每个变体对应一个 darra_error_code(1..=18);未知新码走 Error::Unknown { code, message, hint }#[non_exhaustive],向前容忍)。message / hint 原样透传 Core,不改写。hint 文案权威见 错误码目录

变体
1IoNotFound
2IoDenied
3BadContainer
4BadLicense
5PasswordRequired
6PasswordWrong
7MachineMismatch
8TrialExhausted
9UnsupportedPayload
10UnsupportedPlatform
11ProviderMissing
12ProviderAbiMismatch
13HardwareMissing
14DriverTooOld
15NetworkFailed
16ChecksumMismatch
17Cancelled
18Internal

Display 格式:[码] 描述[码] 描述 | 建议: hint。另有 code() / message() / hint()。实现 std::error::Error

match Session::open("model.darmodel", Some("model.darmkey"), None, None) {
Ok(s) => { let _ = s; }
Err(e) => eprintln!("{e}"), // 含 [码] 描述 | 建议: hint
}

版本兼容

当前绑定版本 1.0.0,与头文件 DARRA_VERSION_* 对齐。version_string() 后缀区分构建风味:客户机必须看到 +runtime。major 不等 = 装错了库,禁止继续。