Direct C-ABI access to every PlatformAdapter operation. Build the
cdylib with the workspace's release-ffi profile:
cargo build --profile release-ffi -p agent-desktop-ffi
The output is target/release-ffi/libagent_desktop_ffi.dylib
(.so on Linux, .dll on Windows) plus a committed C header at
crates/ffi/include/agent_desktop.h.
Four reference topics, loaded as needed:
for every *mut T the FFI hands back to the caller.
last-error contract, enum validation, panic boundary.
AXIsProcessTrusted inheritance when Python/Node dlopens the cdylib,
and the single-owner handle invariant.
example for Python ctypes and a C program that links the dylib.
(ad_get_tree, ad_resolve_element, ad_execute_action,
ad_screenshot, clipboard, launch/close, window ops, observation,
notifications, etc.) from the process's main thread. The FFI enforces
this at runtime in every build profile — a worker-thread call
returns AD_RESULT_ERR_INTERNAL with a diagnostic last-error. On
non-macOS platforms the check is a compile-time true; there is no
runtime cost.
cargo build --release produces panic = "abort" — any Rust panic inside an extern "C" fn will
SIGABRT the host. Use --profile release-ffi to get the correct
panic = "unwind" profile. CI enforces this.
ad_last_error_*remain valid across any number of subsequent successful FFI calls
on the same thread. Only the next failing call rotates them. Cache
the pointer once, read it as many times as you need.
ad_resolve_element result must be released with ad_free_handle(adapter, handle) on the same adapter
that produced it. On macOS this balances the internal CFRetain;
on Windows/Linux the call is a no-op but safe to issue.
ad_execute_action uses the headless policy bydefault, matching CLI ref commands: no focus stealing and no cursor
movement. Use `ad_execute_action_with_policy(...,
AD_POLICY_KIND_FOCUS_FALLBACK, ...)` only when focus-changing behavior is
intended, and AD_POLICY_KIND_PHYSICAL only for explicit physical/headed
input semantics.
clipboard briefly for non-ASCII text insertion. Keep the default headless
policy or set values directly for sensitive text when the target supports it.
#[repr(i32)] enum field is validatedat the C boundary — invalid discriminants return
AD_RESULT_ERR_INVALID_ARGS instead of undefined behavior.
shapes. Anything added or reordered in a later patch is a breaking
change; pin the version of libagent_desktop_ffi you link against.
ad_get_tree returns a raw adapter tree, not the CLI snapshot.Ref IDs are always null, no skeleton/drill-down pipeline is wired
through, and interactive_only / compact follow adapter
semantics which may diverge slightly from the CLI's post-processed
shape. Use ad_find + ad_get / ad_is for point lookups, or
invoke the CLI if you need CLI-parity JSON snapshots.
共 2 个版本