运行库能力查询
migo_query_capabilities
Section titled “migo_query_capabilities”MIGO_API MigoResult MIGO_CALL migo_query_capabilities(MigoCapabilities *out);向已链接的库查询其自身的能力。调用此函数不需要任何已有句柄——这正是它的设计意图:宿主可以在创建 engine、session 或 surface 之前,通过一次调用确认库版本范围与支持的平台类型,而不必等到 migo_session_attach_surface 失败后才发现。此函数是唯一不拒绝未知 abi_version 的入口点(详见为什么用运行时查询)。
参数:
| 参数 | 方向 | 说明 |
|---|---|---|
out |
写 | 指向调用方分配的 MigoCapabilities,调用前须将 struct_size 与 abi_version 填好,其余字段归零。成功后由库填写其余字段;失败时库不写入任何内容。 |
返回:
MIGO_OK— 成功;out中所有字段已由库填写。MIGO_ERROR_INVALID_ARGUMENT—out为NULL,或out->struct_size小于当前 ABI 所定义的最小记录长度。
MIGO_ERROR_UNSUPPORTED_ABI在此入口点故意缺席。询问「哪些版本被接受」的调用方在定义上尚未建立这一前提;拒绝该问题会使调用方无从得到答案。
线程模型:
无句柄依赖,可在任意线程调用。结构体在调用期间独占使用;调用返回后调用方可自由访问。
示例:
/* 在创建 engine 之前探测库能力 */MigoCapabilities caps;memset(&caps, 0, sizeof caps);caps.struct_size = (uint32_t)sizeof caps;caps.abi_version = MIGO_ABI_VERSION_CURRENT;
MigoResult result = migo_query_capabilities(&caps);if (result != MIGO_OK) { fprintf(stderr, "migo_query_capabilities 失败: %d\n", (int)result); return 1;}fprintf(stderr, "migo: abi %u..%u, platform kinds 0x%llx\n", caps.abi_version_min, caps.abi_version_max, (unsigned long long)caps.platform_kinds);
/* 在尝试附接之前确认目标 surface 类型受支持 */if ((caps.platform_kinds & (UINT64_C(1) << MIGO_PLATFORM_WAYLAND_SURFACE)) == 0) { fprintf(stderr, "此构建不支持 Wayland surface\n"); return 1;}MigoCapabilities
Section titled “MigoCapabilities”typedef struct MigoCapabilities { uint32_t struct_size; uint32_t abi_version; uint32_t abi_version_min; uint32_t abi_version_max; uint64_t platform_kinds;} MigoCapabilities;调用方在传入前负责填写前两个字段;库在成功后填写其余三个字段。结构体总大小固定为 24 字节,struct_size 必须位于偏移 0,platform_kinds 必须位于偏移 16——头文件中有静态断言确保这一布局不会悄然变更。
struct_size
Section titled “struct_size”调用方填写。 设为 sizeof(MigoCapabilities)。库用此值判断调用方分配的存储区有多大,从而决定可以安全写入多少字节。若此值小于当前 ABI 所定义的最小记录长度,调用立即返回 MIGO_ERROR_INVALID_ARGUMENT,不写入任何内容——这保证了失败的查询不会被误读为「什么都不支持」的成功查询。
abi_version
Section titled “abi_version”调用方填写。 设为 MIGO_ABI_VERSION_CURRENT(当前值为 1U)。与其他所有入口点不同,此处传入未知版本不会导致 MIGO_ERROR_UNSUPPORTED_ABI;库仍会正常回答并填写 abi_version_min/abi_version_max,供调用方自行判断兼容性。
abi_version_min
Section titled “abi_version_min”库填写。 此构建在其所有入口点上接受的最低 ABI 版本号。调用方若使用低于此值的 abi_version 调用其他函数,将收到 MIGO_ERROR_UNSUPPORTED_ABI。
abi_version_max
Section titled “abi_version_max”库填写。 此构建在其所有入口点上接受的最高 ABI 版本号。调用方使用高于此值的版本调用其他函数时同样会收到 MIGO_ERROR_UNSUPPORTED_ABI。abi_version_min 到 abi_version_max 之间的所有版本均受支持。
platform_kinds
Section titled “platform_kinds”库填写。 64 位掩码,第 N 位置 1 表示 MIGO_PLATFORM_* 值为 N 的 surface 类型可被 migo_session_attach_surface 附接。这与 migo_session_attach_surface 内部执行的检查是同一事实,不是独立的副本。
已定义的平台值(来自 include/migo/surface.h):
| 值 | 常量 | 说明 |
|---|---|---|
| 0 | MIGO_PLATFORM_UNKNOWN |
无效占位值,不应出现在掩码中。 |
| 1 | MIGO_PLATFORM_ANDROID_NATIVE_WINDOW |
Android ANativeWindow。 |
| 2 | MIGO_PLATFORM_WIN32_HWND |
Windows Win32 HWND。 |
| 3 | MIGO_PLATFORM_WINUI_SWAP_CHAIN_PANEL |
Windows WinUI SwapChainPanel。 |
| 4 | MIGO_PLATFORM_MACOS_NS_VIEW |
macOS NSView。 |
| 5 | MIGO_PLATFORM_MACOS_CA_METAL_LAYER |
macOS CAMetalLayer。 |
| 6 | MIGO_PLATFORM_X11_WINDOW |
Linux X11 窗口 ID。 |
| 7 | MIGO_PLATFORM_WAYLAND_SURFACE |
Linux Wayland wl_surface。 |
| 8 | MIGO_PLATFORM_OPENHARMONY_NATIVE_WINDOW |
OpenHarmony OHNativeWindow。 |
| 9 | MIGO_PLATFORM_IOS_UI_VIEW |
iOS UIView。 |
| 10 | MIGO_PLATFORM_IOS_CA_METAL_LAYER |
iOS CAMetalLayer。 |
检测某个平台是否受支持的惯用写法:
if ((caps.platform_kinds & (UINT64_C(1) << MIGO_PLATFORM_X11_WINDOW)) != 0) { /* 此构建支持 X11 surface */}为什么用运行时查询而非编译期探测
Section titled “为什么用运行时查询而非编译期探测”MIGO_C_ABI_HAS_RUNTIME 是一个预处理器宏,它描述的是宿主编译时所针对的平台,而不是实际链接进来的库。宏在编译期展开,对链接阶段一无所知;若宿主代码与某个不同构建目标的 Migo 库链接,宏的值与库的实际能力会产生偏差。
同样,MIGO_PLATFORM_IS_ANDROID、MIGO_PLATFORM_IS_LINUX_GNU 等宏描述的是宿主的编译目标,而 platform_kinds 描述的是链接库所支持的 surface 类型——在某些 CI 或交叉编译场景下两者可以不同。
此外,在引入 migo_query_capabilities 之前,宿主只能通过尝试附接来发现库支持哪些 surface:需要先构建 engine、再创建 session、再创建窗口,才能拿到一个 migo_session_attach_surface 返回的错误码。运行时查询将这一发现提前到了所有资源分配之前,使不支持的构建可以在早期给出明确的诊断信息。
migo_query_capabilities 只有一种失败情况:
MIGO_ERROR_INVALID_ARGUMENT
以下任意一种情况触发:
out为NULL。out->struct_size小于当前 ABI 所定义的最小记录长度(即库无法安全地写满最小有效记录)。
失败时库不写入任何字节到 out。这保证了调用方无法把失败的查询误读为「所有字段均为零」的成功结果。
MIGO_ERROR_UNSUPPORTED_ABI 不会从此入口点返回——这是有意为之的设计,详见为什么用运行时查询。