跳到主要内容

Native-C API 参考

本页记录插件可使用的公开 native-c ABI。内容依据当前 Core 运行时行为整理,面向使用公开 SDK 包的外部开发者,而不是面向阅读 Skydimo 源码的内部开发者。

请使用 Skydimo-Team/Skydimo-SDK 中与 manifest abi 匹配的 SDK 包。

ABI 模型

native-c 插件是进程内共享库。Core 会加载 manifest.json entry 声明的库,查找 skydimo_plugin_get_api,并要求插件填充函数表。

SKYDIMO_EXPORT int32_t skydimo_plugin_get_api(
uint32_t requested_abi_version,
const SkydimoHostApiV1* host,
SkydimoPluginApiV1* out_api);
当前 ABI 版本3
支持版本范围2..3
通用 ABI idskydimo-native-c-v3
Effect ABI idskydimo-effect-c-v3
Controller ABI idskydimo-controller-c-v3
Extension ABI idskydimo-extension-c-v3

out_api->abi_version 必须等于 requested_abi_versionout_api->kind_mask 必须包含 manifest 类型所需的 API family。

Mask含义
SKYDIMO_PLUGIN_KIND_EFFECT提供 SkydimoEffectApiV1
SKYDIMO_PLUGIN_KIND_CONTROLLER提供 SkydimoControllerApiV1
SKYDIMO_PLUGIN_KIND_EXTENSION提供 SkydimoExtensionApiV1

状态码约定

函数类型成功软结果失败
返回 int32_t 的生命周期回调0 或正数部分回调用 0 表示 false、正数表示 true负状态码
validateis_ready正数表示 true0 表示 false负状态码
返回 intptr_t 的读写回调非负字节数0 表示没有数据或写入被限流负状态码
call_json0 表示响应已写入正数表示响应缓冲区太小,并写入 required_len负状态码;可用时响应为错误 JSON

不要让异常、panic 或 unwind 穿过 native-c ABI 函数。插件应在语言边界内捕获运行时失败,并返回负状态码。

通用类型

类型用途
SkydimoStrUTF-8 字符串切片:const char* ptrsize_t len;不要求以 null 结尾
SkydimoRgbRGB 颜色:uint8_t rgb
SkydimoRgbFrameV1宽高与宿主持有的 RGB 像素切片
SkydimoAudioFrameV1音频振幅与 FFT bin 切片
SkydimoOutputDefinitionV1控制器输出端口元数据与能力
SkydimoOutputFrameV1输出 id 与 RGB 颜色切片
SkydimoHardwareCandidateV1由 controller manifest 匹配到的串口或 HID 候选设备
SkydimoDeviceInfoV1控制器提供的设备身份信息

Core 传入的指针只在对应回调约定的生命周期内有效。插件如果需要稍后使用数据,必须自行复制。

设备类型

原生常量对应插件系统中的设备类型字符串:

light, motherboard, dram, gpu, cooler, led_strip, keyboard, mouse,
mouse_mat, headset, headset_stand, gamepad, speaker, virtual, storage,
case, microphone, accessory, keypad, laptop, monitor, unknown

Segment 类型

常量含义
SKYDIMO_SEGMENT_SINGLE单色区域
SKYDIMO_SEGMENT_LINEAR线性灯带
SKYDIMO_SEGMENT_MATRIX二维矩阵
SKYDIMO_SEGMENT_PRESET预设或非逐点可寻址区域

Plugin API 表

SkydimoPluginApiV1skydimo_plugin_get_api 返回的顶层函数表。

字段是否必需说明
size设为 sizeof(SkydimoPluginApiV1)
abi_version必须等于 requested_abi_version
kind_maskSKYDIMO_PLUGIN_KIND_* 按位或
effecteffect 插件必需SkydimoEffectApiV1
controllercontroller 插件必需SkydimoControllerApiV1
extensionextension 插件必需SkydimoExtensionApiV1
shutdown_plugin可选Core 卸载已加载插件包装时调用

Host API 表

Core 会把 SkydimoHostApiV1 传给插件的 create 回调。所有插件类型都会收到通用回调。

回调可用范围用途
log所有插件类型写入带插件上下文的日志
get_plugin_id所有插件类型SkydimoStr 返回当前插件 id
call_jsonEffect、Controller、Extension语言中立的宿主方法调用

call_json 协议

call_json 接收方法名和 UTF-8 JSON 请求,并把 UTF-8 JSON 响应写入调用方提供的缓冲区。

int32_t (*call_json)(
void* host_ctx,
const char* method_ptr,
size_t method_len,
const char* request_ptr,
size_t request_len,
uint8_t* response_ptr,
size_t response_len,
size_t* required_len);

推荐调用流程:

  1. 先使用一个合理大小的响应缓冲区调用。
  2. 如果返回值为正数,按 required_len 分配缓冲区后再调用一次。
  3. 如果返回值为负数,且响应已写入,可按 { "error": "..." } 解析错误信息。

request_ptr == NULLrequest_len == 0 会被视为 JSON null

字节 JSON 形态

多个 call_json 方法接受以下任意字节输入形式:

{ "bytes": [1, 2, 255] }
{ "data": { "base64": "AQD/" } }
{ "data": "plain UTF-8 text" }

字节响应包含:

{
"bytes": [1, 2, 255],
"base64": "AQL/",
"len": 3
}

Effect 插件 API

Core 会为每个启用的灯效分配创建一个 native effect 实例。

回调是否必需调用时机
create(host, out_instance)创建灯效实例
destroy(instance)可选灯效实例被释放
resize(instance, width, height, led_count)可选目标 LED 布局变化
update_params_json(instance, ptr, len)可选灯效参数变化
tick(instance, elapsed_seconds, buffer, len)可选每个渲染帧
is_ready(instance)可选Core 检查异步资源是否就绪

tick 接收 Core 持有的可变 RGB buffer。插件应原地填充,不要保存该指针。

Core 会先消费 __screen_index__screen_region__audio_device_index__audio_settings 等内部运行时参数,再把剩余参数转交给 update_params_json

Effect Host 回调

回调权限返回
effect_audio_capture(avg_size, out_frame)audio:capture正数表示有数据,0 表示暂无帧,负数表示错误
effect_screen_capture(width, height, out_frame)screen:capture正数表示有数据,0 表示不可用,负数表示错误
effect_album_art(width, height, out_frame)media:album_art正数表示有数据,0 表示不可用,负数表示错误

返回的 frame 切片由宿主持有,只在下一次相关 capture 调用前,或回到 Core 前有效。

Effect call_json 方法

方法权限请求响应
hsv_to_rgbhost.hsv_to_rgb{ "h": 0..360, "s": 0..1, "v": 0..1 }{ "r": 0..255, "g": 0..255, "b": 0..255, "rgb": [r,g,b] }
screen.list_displayslist_displaysscreen:capturenull显示器列表
screen.capturecapture_screenscreen:capture{ "width": n, "height": n }{ "width": n, "height": n, "pixels": [0xRRGGBB...] }null
audio.capturecapture_audioaudio:capture{ "avg_size": n }、数字或 null{ "amplitude": n, "bins": [...] }null
media.album_artalbum_artmedia:album_art{ "width": n, "height": n }{ "width": n, "height": n, "pixels": [0xRRGGBB...] }null

Controller 插件 API

Controller 插件只会为 manifest match 规则命中的硬件候选设备创建。

回调是否必需调用时机
create(host, candidate, out_instance)串口或 HID 候选设备匹配后
destroy(instance)可选控制器被释放
validate(instance)可选握手验证;正数接受,0 拒绝候选设备
init(instance)可选注册输出端口与初始化
get_device_info(instance, out_info)可选Core 刷新设备身份
get_output_count(instance)可选Core 读取输出端口数量
get_output(instance, index, out_output)可选Core 读取单个输出端口定义
update(instance, frames, frame_count)可选新 LED 颜色可用
set_output_leds_count(instance, output_id, len, count)可选用户修改可编辑 LED 数量
update_output(instance, output)可选用户修改输出布局
disconnect(instance)可选设备即将断开

Controller 可以在 init 中通过 host 回调推送设备/输出元数据,也可以实现 get_device_infoget_output_countget_output 供 Core 拉取。

Controller Host 回调

回调用途
controller_set_device_info(info)覆盖 manufacturer、model、serial id、device type、image URL、controller id/name、device path
controller_add_output(output)注册或替换输出端口定义
controller_output_led_count(output_id)返回输出端口当前 LED 数量
controller_get_rgb_bytes(output_id, out, out_len)复制最新帧 RGB 字节
controller_write(data, data_len)写入串口或 primary HID transport
controller_read(out, out_len, timeout_ms)从串口或 primary HID transport 读取
controller_hid_send_feature_report(data, data_len)在 primary HID transport 发送 feature report
controller_hid_get_feature_report(out, out_len, report_id)在 primary HID transport 读取 feature report

Controller call_json 方法

方法权限请求响应
systemsystem.infosystem:infonull系统信息对象
hid_interfacescontroller.hid_interfacesnull{ interface_number, port_key, primary } 数组
hid_writecontroller.hid_write{ "data": bytes, "selector": selector }{ "written": n }
hid_readcontroller.hid_read{ "len": n, "timeout_ms": n, "selector": selector }字节响应
hid_send_feature_reportcontroller.hid_send_feature_report{ "data": bytes, "selector": selector }{ "written": n }
hid_get_feature_reportcontroller.hid_get_feature_report{ "len": n, "report_id": n, "selector": selector }字节响应
register_settingcontroller.register_settingcontroller.register_config_param设置项 schema{ "ok": true }
get_settingscontroller.get_settingsnull当前设置对象
trigger_setting_actioncontroller.trigger_setting_action{ "key": "setting_key" }{ "ok": true }

selector 可以是接口号、port_key 字符串,或 { "interface_number": 1 }{ "port_key": "..." } 这类对象。

Extension 插件 API

Extension 运行在 Core 管理的线程中,可接收设备帧投递、UI 页面消息、插件广播事件和扫描请求。

回调是否必需调用时机
create(host, out_instance)扩展线程启动
destroy(instance)可选扩展被释放
start(instance)可选创建后、事件循环前
stop(instance)可选扩展停止
on_scan_devices(instance)可选用户或 Core 请求设备扫描
on_event_json(instance, event, data)可选收到扩展广播事件
on_page_message_json(instance, ptr, len)可选扩展页面发送消息
on_device_frame(instance, port, frames, frame_count)可选收到订阅设备帧

Extension Host 回调

回调用途
extension_lock_leds(port, output_id, indices, locked_count, rejected_count)以扩展身份锁定 LED
extension_unlock_leds(port, output_id, indices)释放 LED 锁
extension_set_leds_rgb(port, output_id, colors)为已锁定 LED 设置颜色

Extension call_json 方法

区域方法
插件信息与路径plugin.infodata_dirplugin.data_dirresource_dirplugin.resource_dir
系统systemsystem.infolist_system_state_topicsget_system_state
页面与通知page_emitnotifynotify_persistentdismiss_persistent
设备register_deviceremove_extension_deviceget_devicesget_device_infoset_device_nicknameset_output_leds_countupdate_output
LED 锁lock_ledsunlock_ledsset_ledsget_led_locks
灯效与资源get_effectsget_effect_paramsget_displaysget_audio_devicesget_media_sessionget_current_media
Scope 状态get_scope_screen_stateget_scope_audio_device_stateset_scope_screen_indexset_scope_screen_regionset_scope_audio_device_index
Scope 控制set_scope_effectset_effectupdate_scope_effect_paramsreset_scope_effect_paramsset_scope_mode_pausedset_scope_powerset_scope_brightness
TCPtcp_connectnet.tcp.connecttcp_writetcp_sendnet.tcp.writetcp_write_allnet.tcp.write_alltcp_readtcp_recvnet.tcp.readtcp_read_exacttcp_recv_exactnet.tcp.read_exacttcp_closenet.tcp.close
HTTPhttp_requestnet.http.requesthttp_openhttp_streamnet.http.streamhttp_readnet.http.readhttp_closenet.http.close
进程spawn_processis_process_alivekill_process
HIDhid_enumeratehid_openhid_open_pathhid_writehid_readhid_send_feature_reporthid_get_feature_reporthid_close

Extension 权限

能力所需权限
system / system.infosystem:info
媒体会话方法media:session
TCP 方法network:tcpnetwork
HTTP 方法network:httpnetwork
进程方法process
HID 方法hardware:hid
系统进程状态system:process
系统窗口焦点状态system:window-focus

常见 Extension 请求形态

Scope 方法可以在顶层或 scope 字段中传入 scope:

{
"scope": {
"port": "device-port",
"output_id": "out1",
"segment_id": "segment-a"
}
}

segment_id 必须搭配 output_idoutput_idsegment_id 对设备级操作是可选的。

register_device 接受:

{
"controller_port": "extension.unique-device",
"manufacturer": "Example",
"model": "Virtual Matrix",
"serial_id": "001",
"device_type": "virtual",
"outputs": [
{
"id": "main",
"name": "Main",
"output_type": "matrix",
"leds_count": 64,
"matrix": { "width": 8, "height": 8, "map": [0, 1, 2] },
"editable": true,
"min_total_leds": 1,
"max_total_leds": 256
}
]
}

lock_ledsunlock_ledsset_leds 使用:

{
"port": "device-port",
"output_id": "main",
"indices": [0, 1, 2],
"colors": [
{ "index": 0, "r": 255, "g": 0, "b": 0 },
[0, 255, 0]
]
}

set_leds 接受 { index, r, g, b } 条目或 RGB 数组。RGB 数组会用数组下标作为 LED index。

安全规则

  • 将每个 ABI 表的 size 字段设为 SDK 结构体大小。
  • 写入 out_api 前先校验 requested_abi_version
  • 字符串或切片需要跨回调保存时必须复制。
  • 除非 SDK 明确说明,否则 host 回调应在 Core 调用插件的线程内使用。
  • 不要阻塞高频回调,例如 effect tick 或 controller update
  • call_json 视为控制路径,不要用它承载高频大块数据。
  • 失败时返回负状态码,并通过 host->log 记录有用上下文。