Skip to content

Rust — FFI / 原生 Artifact

nnrp-ffi 通过 C-compatible ABI 暴露 Rust 拥有的协议和 runtime 行为,供 Python、C#、Unity、Node native loader 和未来语言绑定使用。Preview4 继续保持粗粒度 FFI 边界:调用方通过 handle、event 和 owned buffer 工作,而不是为了每个小字段跨一次 ABI。

Cargo

toml
[dependencies]
nnrp-ffi = "1.0.0-preview.4.0"

Native Artifact 形态

Preview4 发布 transport-scoped native artifacts。角色是 client 还是 server 由 runtime 决定;artifact 名称说明它包含哪个 transport 实现。

TransportArtifact family
TCPnnrp-ffi-transport-tcp-native-<platform>-1.0.0-preview.4.0.zip
QUICnnrp-ffi-transport-quic-native-<platform>-1.0.0-preview.4.0.zip
IPCnnrp-ffi-transport-ipc-native-<platform>-1.0.0-preview.4.0.zip
WebSocketnnrp-ffi-transport-websocket-native-<platform>-1.0.0-preview.4.0.zip

每个包包含 native library、nnrp_ffi.h 和 manifest。Manifest 声明 platform、architecture、transport、library name 和 exported symbols。下游 SDK 加载前必须校验 manifest。

ABI Types

类型说明
NnrpProtocolVersion当前 major version 与 wire format。
NnrpHandle带 kind、id、generation、flags 的 typed handle。
NnrpBufferView只在调用期间有效的 borrowed byte slice。
NnrpFfiStatusStatus code、error family、protocol error 和 detail code。
NnrpFfiDiagnosticStatus 加关联 connection/session/operation/frame id。
NnrpEvent带 handles、message type、frame id、owned payload handle/view 和 diagnostics 的 callback/polling event。

非空 buffer view 必须使用非空指针。非空 runtime-frame event 通过 payload_owner 持有 payload。 Binding 在返回应用 event 前复制 payload,并且必须且只能调用一次 nnrp_buffer_release(payload_owner)。Callback 只能在 callback 期间读取 view,复制后同样释放 owner。

Runtime Requests

Request目的
NnrpClientConnectRequest创建 client connection handle。
NnrpSessionOpenRequest打开 client session。
NnrpSubmitRequest提交一个 operation。
NnrpClientCancelRequest取消 client work。
NnrpServerBindRequest创建 server handle。
NnrpServerAcceptRequest接收 server session。
NnrpServerReceiveSubmitRequest接收 submit 并创建 operation handle。
NnrpServerSendResultRequest发送 result bytes。
NnrpControlRequest发送或校验通用控制面 frame。
NnrpRuntimeFrameSendRequest通过 session 或 operation handle 发送一条 typed Preview4 控制、对象或缓存 frame。字段为 handlemessage_typeframe_idpayload

NnrpRuntimeFrameSendRequest.payload 包含完整编码后的 metadata 与声明 tail。 nnrp_runtime_frame_send 在一次调用中校验 message type、metadata layout、声明长度、handle scope 和 client/server direction,并在返回前 snapshot payload;队列 event 不引用调用方内存。

Exported Functions

Function说明
nnrp_current_protocol_version返回当前 protocol version。
nnrp_client_connect创建 client connection handle。
nnrp_client_open_session创建 client session handle。
nnrp_client_submit提交一个 operation 并入队 event。
nnrp_client_cancel入队 cancel/drop 相关 event。
nnrp_client_await_event从 connection/session 队列 poll 一个 event。
nnrp_client_close关闭 client session。
nnrp_server_bind创建 server handle。
nnrp_server_accept创建 server session handle。
nnrp_server_receive_submit接收 submit 并创建 operation handle。
nnrp_server_send_result入队 result output。
nnrp_server_send_flow_update入队 flow-control output。
nnrp_server_close关闭 server session。
nnrp_control校验并入队通用控制 request。
nnrp_runtime_frame_sendPreview4 控制、对象和缓存 frame 的角色中立粗粒度发送路径。
nnrp_dispatch_event通过 callback 分发一个 borrowed event。

nnrp_control 只作为 Rust-owned integration 内部处理非 Preview4 control code 的 ABI primitive。 SDK 公开 API 使用 nnrp_runtime_frame_send,不得把原始 control-code routing 作为普通应用入口。

C# P/Invoke 示例

csharp
[LibraryImport("nnrp_ffi", EntryPoint = "nnrp_current_protocol_version")]
public static partial NnrpProtocolVersion CurrentProtocolVersion();

[StructLayout(LayoutKind.Sequential)]
public struct NnrpProtocolVersion
{
    public byte Major;
    public byte WireFormat;
}

Python ctypes 示例

python
import ctypes

class NnrpProtocolVersion(ctypes.Structure):
    _fields_ = [("major", ctypes.c_uint8), ("wire_format", ctypes.c_uint8)]

lib = ctypes.CDLL("./libnnrp_ffi.so")
lib.nnrp_current_protocol_version.restype = NnrpProtocolVersion
version = lib.nnrp_current_protocol_version()

边界规则

WARNING

  1. Native artifact 以 transport 为粒度。不要把 client/server 角色包当成隐藏的 native transport bundle。
  2. 浏览器 SDK 使用 nnrp-wasm;不加载 .dll.so.dylib
  3. FFI 调用保持粗粒度。用 handle 和 event polling/callback,不要为每个 Rust struct 字段加一个 ABI 调用。

NNRP Documentation