跳到主要内容

C 用法

面向最终用户的 C 语言接入:怎么装、怎么调、出错怎么查。权威契约是 darra_ai.h,语义冲突以头文件为准;API 逐项说明见 C。

调用链​

全部推理唯一入口是一条链。打开成本只付一次,之后每帧反复推理,不要每图重开:

open / open_plain  →  infer_image × N  →  close
  1. ABI 核对先行:加载后第一件事比对 DARRA_VERSION_DECODE_MAJOR(darra_version()) 与 DARRA_VERSION_MAJOR,不等 = 装错了库,禁止继续。
  2. 打开:加密 .darmodel 走 darra_session_open(先 darra_session_unlock_info 分流,needs_code 时带一次激活码);明文模型走 darra_session_open_plain。
  3. 推理:darra_session_infer_image 每次一张图,结果 JSON;连续帧就是循环调用同一函数,没有一次喂整段视频的接口。
  4. 关闭:darra_session_close 释放;必须等所有在飞推理结束后再关,NULL 安全。

错误两步走:先看返回码(非 0 = 失败),再调 darra_last_error 取 code / message / hint,hint 就是给最终用户的修复建议。约定四条:

  • SDK 返回的堆字符串一律 darra_string_free,禁止 free / delete[];调用方自己 malloc 的自己 free。
  • 结构体首字段 size 一律填 sizeof(...),漏填返回 DARRA_INTERNAL。
  • 推理是阻塞调用,不承诺硬实时;PLC 侧必须在扫描周期外进程 / 线程调用。
  • 激活码只在打开时用一次,推理函数永不收码;本机已绑定的模型打开时不再要码。

前置依赖​

项目要求
操作系统Windows x64 / Linux x86_64 / Linux ARM64(RK3588)。macOS 不在 v1,不是即将支持;Windows 无 RKNN
编译器MSVC(/utf-8)/ GCC / Clang,C11 或更高
头文件darra_ai.h
运行库Windows:DarraAI.Core.dll;Linux:libCore.so
模型加密 .darmodel,或明文 .onnx / .pdmodel / TorchScript 归档 .pt / .pth
Provideronnx-cpu 等由 Studio 环境管理器或 darra-env-setup 提前部署;SDK 不下载、不安装、不代装系统驱动

安装​

从 下载 取语言包 darra-ai-c-sdk.zip(头文件 + import lib + 示例)或对应平台内核包。Windows x64 用包 darra-ai-core-windows-x64.zip(含 DarraAI.Core.dll、darra_ai.h、import lib、darra-selftest):

cl /utf-8 /Fe:my_app.exe main.c DarraAI.Core.lib /I include

运行目录必须带 DarraAI.Core.dll。MSVC 消费方加 /utf-8(头文件 UTF-8 无 BOM,注释全中文)。

Linux x64(包 darra-ai-core-linux-x64.tar.gz,含 libCore.so + 头文件)与 Linux ARM64(包 darra-ai-core-linux-arm64.tar.gz,RK3588 板端与客户板共用)同一条编译行:

gcc -o my_app main.c -I include -L. -ldarraai_core -Wl,-rpath,'$ORIGIN'

CMake 片段:

add_executable(my_app main.c)
target_include_directories(my_app PRIVATE ${SDK_PATH}/include)
# Windows 链接 DarraAI.Core;Linux 链接 darraai_core
target_link_libraries(my_app PRIVATE DarraAI.Core)

只交付 x64 / ARM64,两平台均单调用约定,无 __stdcall 变体。装运行时包到系统目录时可能需要管理员。

快速开始​

最小可跑程序:核对 ABI → unlock_info 分流打开 → 推理一张图 → 释放并关闭。模型、图片、激活码走命令行参数。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "darra_ai.h"

static int fail(const char* where)
{
darra_error_t e;
memset(&e, 0, sizeof(e));
e.size = sizeof(e);
darra_last_error(&e);
fprintf(stderr, "%s 失败\n code=%d\n message=%s\n hint=%s\n",
where, (int)e.code, e.message, e.hint);
return 1;
}

static uint8_t* read_all(const char* path, size_t* out_len)
{
FILE* f = fopen(path, "rb");
long n; size_t got; uint8_t* buf;
if (f == NULL) return NULL;
if (fseek(f, 0, SEEK_END) != 0) { fclose(f); return NULL; }
n = ftell(f);
if (n <= 0) { fclose(f); return NULL; }
rewind(f);
buf = (uint8_t*)malloc((size_t)n);
if (buf == NULL) { fclose(f); return NULL; }
got = fread(buf, 1, (size_t)n, f);
fclose(f);
if (got != (size_t)n) { free(buf); return NULL; }
*out_len = got;
return buf;
}

int main(int argc, char** argv)
{
const char* model = (argc > 1) ? argv[1] : "model.darmodel";
const char* image_path = (argc > 2) ? argv[2] : "photo.jpg";
const char* key = (argc > 3) ? argv[3] : NULL;
darra_session* s = NULL;
char* results = NULL;
uint8_t* image = NULL;
size_t image_len = 0;
darra_image_desc desc;
int32_t rc; int exit_code = 1;

if (DARRA_VERSION_DECODE_MAJOR(darra_version()) != DARRA_VERSION_MAJOR) {
fprintf(stderr, "ABI 不匹配: %s\n", darra_version_string());
return 1;
}

{
darra_unlock_info inf;
memset(&inf, 0, sizeof(inf));
inf.size = sizeof(inf);
rc = darra_session_unlock_info(model, &inf);
if (rc != DARRA_OK) return fail("darra_session_unlock_info");
if (inf.needs_code) {
if (key == NULL || key[0] == '\0') {
fprintf(stderr, "%s\n", inf.hint[0] ? inf.hint : inf.message);
return 1;
}
rc = darra_session_open(model, NULL, key, NULL, &s);
} else {
rc = darra_session_open(model, NULL, NULL, NULL, &s);
}
if (rc != DARRA_OK) return fail("darra_session_open");
}

image = read_all(image_path, &image_len);
if (image == NULL) { fprintf(stderr, "读图片失败: %s\n", image_path); goto done; }

memset(&desc, 0, sizeof(desc));
desc.size = sizeof(desc);
desc.format = DARRA_IMAGE_AUTO;

rc = darra_session_infer_image(s, image, image_len, &desc, &results);
if (rc != DARRA_OK) { fail("darra_session_infer_image"); goto done; }
printf("[results] %s\n", results);
exit_code = 0;

done:
free(image);
if (results) darra_string_free(results);
darra_session_close(s);
return exit_code;
}

明文模型一行开(Studio 试跑 / 客户自有无需加密模型),与加密包同一推理路径:

darra_session* s = NULL;
int32_t rc = darra_session_open_plain("model.onnx", NULL, &s);

装上不等于跑得通:打开后拿真实图片确认结果 JSON 正常再交付现场。失败码与修复建议见 错误码。

按场景索引​

场景什么时候用
推理入门第一次接入或部署验收,单模型单张图的最小调用链
视频连续推理相机逐帧进图,满队列丢最旧帧保最新画面
图片队列一次上百张突发进队列,容量与溢出策略由应用定
并行推理同模型多路并发提交,推理线程数独立可配
多模型并行多模型或多卡分槽,按 Weight 分并发槽份额

运行时/错误码详见 运行时 与 错误码。

设备池​

多张卡按每卡权重分活,不是插队。和同一张卡上的推理池不是一回事。 打开没成功:返回非 0,用 darra_last_error 看码。路径空是 DARRA_INTERNAL;文件不在、未激活、缺 Provider 各有自己的码。运行库缺符号时加载失败,不是关了再开。

darra_device_pool* p = NULL;
darra_device_pool_open_plain("model.onnx", NULL, NULL, &p);
uint64_t t = 0; char* json = NULL;
darra_device_pool_submit(p, image, image_len, &desc, -1, &t);
darra_device_pool_wait(p, t, &json);
darra_device_pool_close(p);