跳到主要内容

C# SDK 概述

开发 AI 推理应用的 .NET 类库。P/Invoke 薄封装,零密码学;唯一契约为 Core/include/darra_ai.h

当前版本

本文档对应 C# SDK v1.0.0(与 darra_ai.hDARRA_VERSION_* 对齐)。运行时版本通过 AiRuntime.VersionString 查询,形如 "1.0.0+runtime" / "1.0.0+authoring"。加载后静态构造核对 darra_version major == 1,不等立即失败。

安装

Install-Package Darra.AI.Runtime

或使用 .NET CLI:

dotnet add package Darra.AI.Runtime

程序集 / PackageId = Darra.AI.Runtime(工程名 Darra.AI.Studio.Runtime,过仓根前缀门槛)。Studio 是本包的消费方,不是宿主目录。

native 必须随包

客户交付包必须带 runtimes/win-x64/native/darraai_core.dll。缺 native 的纯托管包只能编译引用,不能推理;运行时报 AiLoadException,不影响编译 / pack。本包不内嵌、不伪造 native dll。

环境要求

  • 操作系统: Windows x64;Linux x86_64 / ARM64。macOS 不在 v1;只交付 x64 / ARM64
  • 运行时: .NET 8.0
  • native: darraai_core(缺库时报 AiLoadException
  • 驱动 / OS 级依赖: SDK 不代装(NVIDIA 驱动过旧、RK3588 板镜像缺 NPU 驱动只诊断不代劳)。Windows 上指名 edge-rknn 由 Core 返回 UNSUPPORTED_PLATFORM

快速开始

推荐方式
  1. AI Studio 导出加密容器 .darmodel 与授权 .darmkey
  2. 客户机安装 Darra.AI.Runtime(须带 native)
  3. 代码中 AiSession.OpenInferImage
using Darra.AI.Runtime;

// 静态构造已核 ABI。基础检测:推荐哪套包、装了没有(不联网)。
AiEnvCheck env = AiEnvironment.Check();
Console.Error.WriteLine(env.Message);
if (!env.Ready)
{
AiEnvironment.EnsureReady((percent, stage) =>
Console.Write($"\r环境准备 [{stage,-8}] {percent,5:0.0}% "));
Console.WriteLine();
}

using var session = AiSession.Open("model.darmodel", keyPath: "model.darmkey");
Console.WriteLine("[meta] " + session.MetaJson());

byte[] photo = File.ReadAllBytes("photo.jpg");
string results = session.InferImage(photo, ImageDesc.Auto());
Console.WriteLine("[results] " + results);

失败时捕获对应子类,Hint 即 error-catalog 给最终用户的修复建议:

try { /* Open / InferImage */ }
catch (AiException ex)
{
Console.Error.WriteLine(ex.Message); // 含 [码] 描述 | 建议: hint
}

备选方式: 明文 ONNX 试跑

Studio 试跑 / 客户自有无需加密模型,走同一推理路径,只跳过容器解码与验票:

using Darra.AI.Runtime;

AiRuntime.Ensure("cpu-only");
using var session = AiSession.OpenPlain("model.onnx");
byte[] jpg = File.ReadAllBytes("photo.jpg");
string json = session.InferImage(jpg, ImageDesc.Encoded());
Console.WriteLine(json);

训练格式(.pt / .pth / Paddle)不是运行时载荷,会抛 AiUnsupportedPayloadException

何时用哪种
  • 加密容器 — 生产环境,.darmodel + .darmkey(或密码),推荐。
  • 明文 ONNX — Studio 试跑 / 客户自有未加密模型。

工业相机裸缓冲 BGR888 + 取消安装

using Darra.AI.Runtime;

// UI「取消」从 UI 线程调;不要在 progress 回调里调 Cancel。
CancellationToken token = /* UI token */;
token.Register(AiRuntime.Cancel);

try
{
AiRuntime.Ensure("nvidia-gpu", progress: (p, s) => Console.WriteLine($"{s} {p:0}%"));
}
catch (AiCancelledException)
{
// 半成品已清理,需要时重新 Ensure 即可
return;
}

using var session = AiSession.Open("model.darmodel", password: Environment.GetEnvironmentVariable("DARRA_MODEL_PASSWORD"));

// frame = 相机一帧,1920x1080 BGR 紧凑
byte[] frame = GrabBgrFrame(); // 调用方自己的采集
var desc = ImageDesc.Bgr888(width: 1920, height: 1080, stride: 0);
string results = session.InferImage(frame, desc);
Console.WriteLine(results);

裸缓冲禁止 ImageDesc.Auto()(嗅探不出通道序)。stride = 0 表示紧凑排列(= width × 3)。

keyPathpassword 至少给一个;都给则 key 文件优先验票。preferProvider 指名但不可用 = fail-closed,绝不静默降级。

高级 API

功能说明
环境检测 (AiEnvironment.Check)不联网:推荐哪套 Provider、装了没有
自动安装 (AiRuntime.Ensure / AiEnvironment.EnsureReady)没装就探测→选包→下载→校验→解压登记;幂等
取消安装 (AiRuntime.Cancel)任意线程可调;进度回调内禁止
诊断 (AiDiagnostics.Collect)本机环境 JSON(去敏);耗时可到数百毫秒,禁止放进 PLC 扫描周期
会话选项 (OpenEx / OpenPlainEx)线程数 / CPU 亲和;禁止改 Windows ReservedCpuSets、禁止动 PLC 隔离核
authoring仅 authoring 构建导出;runtime 缺符号时抛 AiAuthoringUnavailableException
AiRuntime.Ensure("cpu-only");
string diag = AiDiagnostics.Collect();
using var session = AiSession.OpenEx(
"model.darmodel",
keyPath: "model.darmkey",
options: new SessionOptions { IntraOpThreads = 2, InterOpThreads = 1 });

进度回调(AiRuntime.Ensure)在 SDK 工作线程触发,回调内禁止调用任何 Darra AI API(含 Cancel)。回调抛出的异常会被吞掉,避免穿过 native 边界。

API 总览

类别属性类型访问说明
AiSession 打开OpenAiSession静态打开加密容器(.darmodel,DARM1)。keyPath 与 password 至少给一个;都给则 key 文件优先验票。preferProvider 指名但不可用 = fail-closed
OpenPlainAiSession静态打开明文 .onnx 建会话。与 Open 同一推理路径,只跳过容器解码与验票
OpenExAiSession静态打开加密容器并传入 SessionOptions(线程数 / CPU 亲和)。options 为 null = 等同 Open。native 缺符号时抛 AiLoadException
OpenPlainExAiSession静态打开明文 .onnx 并传入 SessionOptions。options 为 null = 等同 OpenPlain
AiSession 元信息MetaJsonstring方法会话元信息 JSON。首次向 native 取一次并缓存;无需调用方释放
Taskstring只读任务短名(detect / classify / segment / pose / ocr / anomaly)。缺席为空串
LabelsIReadOnlyList<string>只读类别标签。缺席为空列表,永不 null
InputWidthuint只读模型输入宽。0 = 容器头未写 / 未知
InputHeightuint只读模型输入高。0 = 容器头未写 / 未知
InputChannelsuint只读模型输入通道。0 = 容器头未写 / 未知
Layoutstring只读张量布局(NCHW / NHWC)。缺席为空串
PayloadKindstring只读载荷类型(onnx / trt-engine / openvino / rknn)。缺席为空串
ProviderIdstring只读实际选中的 Provider(不是 prefer 入参)。缺席为空串
Encryptedbool只读是否加密容器会话。明文 ONNX 为 false
AiSession 推理InferImagestring方法对一张图片跑推理,结果 JSON。重载:byte[] / ReadOnlySpan<byte>。阻塞调用,不承诺硬实时。同一会话可并发;Dispose 禁止与在飞调用并发
Disposevoid方法关闭会话并释放全部资源(含解密明文窗口清零)。重复 Dispose 安全。实现 IDisposable
AiRuntimeExpectedMajorint常量头文件 DARRA_VERSION_MAJOR。静态构造已核对此值(1)
VersionPackeduint只读打包版本 (major<<16)|(minor<<8)|patch
VersionStringstring只读形如 "1.0.0+runtime" / "1.0.0+authoring" 的静态字符串。禁止释放
Ensurevoid静态确保 Provider / profile 已装好。细包:onnx-cpu / onnx-cuda / onnx-openvino / onnx-trt-ep / trt-native / edge-rknn;场景包:cpu-only / nvidia-gpu / intel-iap / amd-dml / board-rk3588;null = 按硬件探测自动选。offlineZip 非空 = 离线安装。幂等
Cancelvoid静态请求取消当前在飞的 Ensure。可从任意线程调(含 UI 线程);进度回调内部禁止。没有在飞的 Ensure 时为 no-op
ImageDescFormatImageFormat只读图像输入格式。Auto/Encoded 时 Width/Height/Stride 忽略(填 0)
Widthuint只读裸缓冲宽。Rgb888/Bgr888 时必填(>0)
Heightuint只读裸缓冲高。Rgb888/Bgr888 时必填(>0)
Strideuint只读每行字节数。0 = 紧凑排列(= Width×3)
AutoImageDesc静态编码字节流,按魔数自嗅探(JPG/PNG/BMP)。裸缓冲禁止用 Auto
EncodedImageDesc静态显式编码字节流(JPG/PNG/BMP);v1 行为同 Auto
Rgb888ImageDesc静态裸 RGB888。stride=0 表示紧凑
Bgr888ImageDesc静态裸 BGR888(工业相机常见)。stride=0 表示紧凑
异常AiException.Codeint?只读darra_error_code 整数值;绑定侧加载/ABI/authoring 缺符号为 null
AiException.Hintstring只读修复建议(error-catalog 标准文案,可为空串),可原样展示给最终用户
AiLoadExceptionAiException抛出native 内核加载失败或 ABI 不匹配。Code 恒为 null
AiAuthoringUnavailableExceptionAiException抛出runtime 构建没有 authoring 符号。文案固定:「当前 SDK 为 runtime 构建,不含加密/签发能力」
AiIoNotFoundExceptionAiException抛出DARRA_IO_NOT_FOUND (1):文件不存在(容器/授权/图片/离线包路径错)
AiIoDeniedExceptionAiException抛出DARRA_IO_DENIED (2):文件存在但读/写被拒
AiBadContainerExceptionAiException抛出DARRA_BAD_CONTAINER (3):.darmodel 损坏 / 非 DARM1 / 被截断篡改
AiBadLicenseExceptionAiException抛出DARRA_BAD_LICENSE (4):.darmkey 损坏或与容器不配对
AiPasswordRequiredExceptionAiException抛出DARRA_PASSWORD_REQUIRED (5):该容器需要密码但调用方没给
AiPasswordWrongExceptionAiException抛出DARRA_PASSWORD_WRONG (6):密码错误
AiMachineMismatchExceptionAiException抛出DARRA_MACHINE_MISMATCH (7):绑机授权在非目标机器上使用
AiTrialExhaustedExceptionAiException抛出DARRA_TRIAL_EXHAUSTED (8):试用计次已用完
AiUnsupportedPayloadExceptionAiException抛出DARRA_UNSUPPORTED_PAYLOAD (9):载荷类型在当前平台/Provider 下不支持
AiUnsupportedPlatformExceptionAiException抛出DARRA_UNSUPPORTED_PLATFORM (10):整个 OS/架构不在支持矩阵
AiProviderMissingExceptionAiException抛出DARRA_PROVIDER_MISSING (11):需要的运行时 Provider 包未安装
AiProviderAbiMismatchExceptionAiException抛出DARRA_PROVIDER_ABI_MISMATCH (12):Provider 包与内核 ABI 不匹配
AiHardwareMissingExceptionAiException抛出DARRA_HARDWARE_MISSING (13):未探测到所需硬件
AiDriverTooOldExceptionAiException抛出DARRA_DRIVER_TOO_OLD (14):驱动版本低于 Provider 包要求(SDK 不代装)
AiNetworkFailedExceptionAiException抛出DARRA_NETWORK_FAILED (15):清单 / 运行时包下载失败
AiChecksumMismatchExceptionAiException抛出DARRA_CHECKSUM_MISMATCH (16):下载包或离线包 sha256 校验不过
AiCancelledExceptionAiException抛出DARRA_CANCELLED (17):操作被取消(AiRuntime.Cancel)
AiInternalExceptionAiException抛出DARRA_INTERNAL (18):SDK 内部错误;也用于调用方参数契约违反。未知新码兜底为 AiException 基类,Code 原样保留
ImageFormat 枚举值
public enum ImageFormat
{
Auto = 0, // 按字节魔数自嗅探编码格式(JPG/PNG/BMP)。裸缓冲禁止用 Auto
Encoded = 1, // 显式声明为已编码字节流(JPG/PNG/BMP);v1 行为同 Auto
Rgb888 = 2, // 裸缓冲,RGB 三通道 8bit,须给宽高
Bgr888 = 3, // 裸缓冲,BGR 三通道 8bit,须给宽高
}
AiErrorCode 枚举值
public enum AiErrorCode
{
Ok = 0,
IoNotFound = 1,
IoDenied = 2,
BadContainer = 3,
BadLicense = 4,
PasswordRequired = 5,
PasswordWrong = 6,
MachineMismatch = 7,
TrialExhausted = 8,
UnsupportedPayload = 9,
UnsupportedPlatform = 10,
ProviderMissing = 11,
ProviderAbiMismatch = 12,
HardwareMissing = 13,
DriverTooOld = 14,
NetworkFailed = 15,
ChecksumMismatch = 16,
Cancelled = 17,
Internal = 18,
}

ABI 核对

加载 native 时静态构造核对 darra_version major 必须等于 AiRuntime.ExpectedMajor(1)。库找不到或位数不匹配抛 AiLoadException;major 不等亦抛 AiLoadException,禁止继续调用。

AiRuntime.Ensure 启动时:已装且匹配 → 直接成功(回调收到一次 "done", 100)。进程内串行;取消或失败不留半成品。

错误处理

失败时 ThrowIfError 取本线程 darra_last_error,再抛对应子类。Message 格式为 [码] 描述 | 建议: hintHint 原文透传,不改写。

string ver = AiRuntime.VersionString;          // "1.0.0+runtime" / "1.0.0+authoring"
uint packed = AiRuntime.VersionPacked; // (major<<16)|(minor<<8)|patch
try
{
using var session = AiSession.Open("model.darmodel", keyPath: "model.darmkey");
}
catch (AiException ex)
{
Console.Error.WriteLine(ex.Message);
Console.Error.WriteLine(ex.Hint);
}

版本兼容

当前 C# SDK v1.0.0。绑定与 DarraAI.Core 必须同一发布批次;major 变 = ABI 破坏,须成套升级。OpenEx / OpenPlainEx 在旧 native 上缺符号时抛 AiLoadException(提示升到同一批次)。

authoring(Authoring.EncryptOnnx / IssueKey / FingerprintPerturb)仅 authoring 构建导出;本 NuGet 面向客户机 runtime,缺符号时抛 AiAuthoringUnavailableException:「当前 SDK 为 runtime 构建,不含加密/签发能力」。调用顺序:扰动 → 加密 → 签发。