C#
开发 AI 推理应用的 .NET 类库。命名空间 Darra.AI.Runtime。公开包是 runtime 构建:打开已签发的 .darmodel 做推理,物理上没有加密 / 签发符号。
安装
先取得正式交付的 Darra.AI.Runtime.1.0.0.nupkg,放入应用目录下的 packages 文件夹。下面从这个本地源安装。2026-09-22 核查公共 NuGet 索引尚无此包,不能把默认源安装成功当作前提。
- NuGet 包管理器
- 直接引用 DLL
Install-Package Darra.AI.Runtime -Version 1.0.0 -Source .\packages
或使用 .NET CLI:
dotnet add package Darra.AI.Runtime --version 1.0.0 --source ./packages
程序集 / PackageId = Darra.AI.Runtime。目标框架 .NET 8。客户交付包必须带 runtimes/win-x64/native/Core.dll;缺 native 只能编译引用,不能运行。应用进程使用 x64。
- 从 下载页面 或官方输出
bin/AI SDK/{Debug|Release}/获取Darra.AI.Runtime.dll和Darra.AI.Runtime.xml - 在项目中添加引用:
<Reference Include="Darra.AI.Runtime">
<HintPath>lib\Darra.AI.Runtime.dll</HintPath>
</Reference>
- 将正式 runtime 构建的
Core.dll与应用一起交付,或设置进程环境变量DARRA_AI_CORE_PATH指向库文件或其所在目录。绑定入口名称为Core,Windows 也接受DarraAI.Core.dll;Linux 文件名为libCore.so。不要把 Studio 的 authoring 库交付给现场客户。
将 Darra.AI.Runtime.xml 与 DLL 放在同一目录,即可获得完整的 IntelliSense 方法提示和注释。
环境要求
| 项目 | 要求 |
|---|---|
| 操作系统 | Windows x64(当前客户交付重点)。Linux 包的发布状态见下载页面;macOS 不在支持矩阵 |
| 运行时 | .NET 8(目标框架);应用进程使用 x64 |
| native | DarraAI.Core,随包 runtimes/win-x64/native/ 或 DARRA_AI_CORE_PATH |
| 权限 | 装运行时包到系统目录时可能需要管理员;驱动 / OS 级依赖 SDK 不代装 |
| 不在支持矩阵 | macOS;Windows 上的 edge-rknn |
Windows 无 RKNN:指名 edge-rknn 抛 AiUnsupportedPlatformException,收到 rknn 载荷抛 AiUnsupportedPayloadException。Linux 加密 Provider 可信加载尚不支持。
功能概览
数据一律走属性。下表是常用入口(不列全量公开符号)。C# 绑定无 Gray8 / Rgba 格式。
| 类别 | 属性 | 类型 | 访问 | 说明 |
|---|---|---|---|---|
| 版本 | AiRuntime.VersionString | string | 只读 | 形如 1.0.0+runtime。客户机必须看到 +runtime |
AiRuntime.VersionPacked | uint | 只读 | 打包版本 major*65536 + minor*256 + patch | |
| 会话打开 | AiSession.Open | AiSession | 静态 | 打开已签发容器 .darmodel。不收激活码;指名 Provider 不可用 = fail-closed |
AiSession.OpenPlain | AiSession | 静态 | 打开明文模型(.onnx / .pdmodel)。与 Open 同一推理路径,只跳过容器解码与验票 | |
AiSession.OpenEx | AiSession | 静态 | 打开加密容器并传入 SessionOptions。走 darra_session_open_ex | |
AiSession.Dispose | void | 方法 | 关闭会话并释放资源。重复 Dispose 安全。实现 IDisposable | |
| 会话元信息 | AiSession.MetaJson | string | 方法 | 会话元信息 JSON(有缓存) |
AiSession.Task | string | 只读 | detect / classify / segment / pose / ocr / anomaly。缺席为空串 | |
AiSession.Labels | IReadOnlyList<string> | 只读 | 类别标签。缺席为空列表,永不 null | |
AiSession.InputWidth / InputHeight / InputChannels | uint | 只读 | 模型输入宽高与通道。0 = 容器头未写 / 未知 | |
AiSession.Layout | string | 只读 | 张量布局(NCHW / NHWC)。缺席为空串 | |
AiSession.PayloadKind | string | 只读 | onnx / paddle / trt-engine / openvino / rknn | |
AiSession.ProviderId | string | 只读 | 实际选中的 Provider(不是 preferProvider 入参) | |
AiSession.Encrypted | bool | 只读 | 是否加密容器会话。明文模型为 false | |
| 推理 | AiSession.InferImage | string | 方法 | 对一张图(一帧)跑推理,返回结果 JSON。连续帧循环调用。不承诺硬实时 |
| 运行时 | AiEnvironment.Check | AiEnvCheck | 静态 | 本地环境检测。禁止在 PLC 扫描周期等实时路径调 |
AiDiagnostics.Collect | string | 静态 | 本机环境诊断 JSON;去敏。禁止在 PLC 扫描周期等实时路径调 | |
| 错误 | AiException.Code | int? | 只读 | darra_error_code;绑定侧错误为 null |
AiException.Message | string | 只读 | 错误描述 | |
AiException.Hint | string | 只读 | 修复建议,与错误码目录逐字一致,可原样展示给最终用户 | |
AiLoadException | AiException | 抛出 | native 加载失败或 ABI 不匹配。Code 恒为 null |
一模型一实例:一个 AiSession = 一份已加载模型 + 一个 Provider。多模型或多份同模型 = 多会话,API 完全相同。
快速开始
- 用 AI Studio 导出
.darmodel,由模型作者交付激活码 - 客户机安装
Darra.AI.Runtime(须带 native) Probe:未激活则Activate(只要一次出厂激活码);已绑机Open→ 读属性 →InferImage
客户还需要与 Core 信任根匹配的正式签名 Provider。2026-09-22 抽查公开 R2 的 CPU / DirectML 包未包含签名清单,因此“包能下载”尚不能代表“加密模型可交付”。正式签名包准备好后,再验收客户机上的激活与实际推理。
using Darra.AI.Runtime;
try
{
// 环境已由 Studio 或部署人员准备;这里仅查看本地诊断。
Console.WriteLine(AiEnvironment.Check().Message);
if (!AiSession.TryOpen("model.darmodel", out var session, out UnlockInfo info))
{
Console.Error.WriteLine(info.Display);
// 仅 info.NeedsCode 为 true 时,向用户显示激活码输入框。
return;
}
using var active = session!;
byte[] photo = File.ReadAllBytes("photo.jpg");
Console.WriteLine(active.InferImage(photo, ImageDesc.Encoded()));
}
catch (AiException ex)
{
Console.Error.WriteLine(ex.Message);
Console.Error.WriteLine(ex.Hint);
}
用户输入激活码后调用一次 Activate;参数来自密码输入框,不硬编码、不写入日志。随后复用返回的会话。已激活模型继续用 TryOpen,每张图片只调 InferImage:
using var session = AiSession.Activate(modelPath, activationCode);
string json = session.InferImage(photoBytes, ImageDesc.Encoded());
TryOpen 处理激活状态,但文件、环境和 native 加载异常仍需应用统一捕获。SDK 不弹窗;桌面应用展示 UnlockInfo.Display 或 AiException.Hint,提供重试、取消和本地诊断入口。AiEnvironment.Check().Ready 只表示发现推荐 Provider 的安装登记,不等于模型已加载、签名已通过或推理成功。进度、离线安装和错误处理见环境准备。
明文模型
Studio 试跑 / 客户自有无需加密模型,走同一推理路径,只跳过容器解码与验票:
using Darra.AI.Runtime;
// 先部署与 SDK 匹配的 onnx-cpu Provider,再打开模型。
using var session = AiSession.OpenPlain("model.onnx", preferProvider: "onnx-cpu");
byte[] jpg = File.ReadAllBytes("photo.jpg");
string json = session.InferImage(jpg, ImageDesc.Encoded());
Console.WriteLine(json);
明文路径:.onnx;.pdmodel(同目录须有 .pdiparams)或含二者的目录。Paddle 是运行时载荷。.pt / .pth 抛 AiUnsupportedPayloadException。
约定
惰性加载
类型初始化只注册原生库解析器。第一次调用碰 Core 的 API 才真正加载 Core.dll。加载后立即核 ABI:major ≠ 1 抛 AiLoadException,禁止继续调用。
属性而非 GetXxx()
会话元信息走只读属性(session.Task / session.Labels / session.InputWidth …),全部从 MetaJson() 的 JSON 派生。缺字段不编默认 640/80/17。
异常而非错误码
失败时抛 AiException 子类。绑定把 C 的 int32_t 错误码翻译成异常;调用方不必自己取错误槽。未知新码兜底为 AiException 基类,Code 原样保留。详见 错误码。
Authoring.EncryptOnnx / Authoring.IssueKey / Authoring.FingerprintPerturb 只随 AI Studio 的 authoring 构建导出。客户机 runtime 包物理上没有这些符号;公开文档不把它们当作 runtime API。
完整示例
using Darra.AI.Runtime;
byte[] jpg = File.ReadAllBytes("photo.jpg");
try
{
using var session = AiSession.Open("model.darmodel");
Console.WriteLine(session.Task);
Console.WriteLine(session.PayloadKind);
Console.WriteLine(session.ProviderId);
Console.WriteLine(session.InferImage(jpg, ImageDesc.Auto()));
}
catch (AiException ex)
{
Console.Error.WriteLine(ex);
}