[P1] ARM64 iOS 上 RustBuffer 结构体跨 FFI 传参 ABI 不兼容,需全部改为 out-pointer 方式 #36
Loading…
x
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
背景
在 ARM64 iOS (iPhone 17 Pro Max 模拟器) 上,Swift 与 Rust 之间通过 C ABI 传递
RustBuffer(24 字节结构体,u64+u64+*mut u8)时,超过 16 字节的结构体应通过间接指针传递,但 Swift 和 C/Rust 编译器在内存布局上存在不一致,导致跨 FFI 传参时字段损坏。已验证的修复方案:将结构体参数拆分为独立的
len/data/capacity等原始类型参数,通过 out-pointer 传递。已修复的函数
parseMarkdown-- 使用ffi_zx_document_ffi_parse_markdown_separate(len, data, out_capacity, out_len, out_data, out_error_code)ffi_zx_document_ffi_rustbuffer_from_bytes-- 使用ffi_zx_document_ffi_rustbuffer_from_bytes_separate(len, data, out_capacity, out_len, out_data)ffi_zx_document_ffi_rustbuffer_free-- 使用ffi_zx_document_ffi_rustbuffer_free_separate(capacity, len, data)待修复的函数(仍用旧的 struct-passing)
以下 Rust FFI 函数仍然通过结构体传参
RustBuffer,需要改为 out-pointer 方式:输入路径(Swift → Rust 传 RustBuffer 参数):
pushReadingEvent(RustBuffer event)-- 阅读事件上报updateReadingPosition(RustBuffer materialId, RustBuffer position)-- 阅读位置更新readTextStats(RustBuffer filePath)-- 文本统计readImageMeta(RustBuffer filePath)-- 图片元数据detectMaterialType(RustBuffer filePath)-- 文件类型检测searchMarkdownBlocks(RustBuffer blocks, RustBuffer query)-- 搜索searchTextContent(RustBuffer content, RustBuffer query)-- 搜索输出路径(Rust → Swift 返回 RustBuffer):
createNoteAnchor-- 返回 RustBufferexportPendingEvents-- 返回 RustBufferdetectMaterialType-- 返回 RustBufferreadImageMeta-- 返回 RustBufferreadTextStats-- 返回 RustBuffersearchMarkdownBlocks-- 返回 RustBuffersearchTextContent-- 返回 RustBufferparseText-- 返回 RustBuffer临时影响
iOS 端
MaterialReaderView中collector.open()/collector.close()已临时注释,因为pushReadingEvent仍使用旧的 struct-passing 方式,调用会 crash。实现方式
参照已修复的
parseMarkdown和from_bytes函数,在 Rust 侧新增 out-pointer 版本的extern "C"函数,Swift 侧通过@_silgen_name声明并调用。关联
crates/zx_document_ffi/src/lib.rsbindings/ios/generated/zx_document.swift(需 patch)进度汇报 (2026-06-05)
根因确认
ARM64 iOS 上 Swift ↔ Rust 之间传递
RustBuffer(24 字节结构体)存在 ABI 兼容性问题:ForeignBytes结构体字段被错误读取(读到 markdown 文本内容而非指针)RustBuffer的 capacity/len/data 字段损坏已验证的修复方案
将结构体参数拆分为独立的原始类型参数(
Int32/UnsafeRawPointer/UInt64),通过 out-pointer 传递。已修复
parseMarkdownffi_zx_document_ffi_parse_markdown_separate(len, data, ...)rustbuffer_from_bytesffi_zx_document_ffi_rustbuffer_from_bytes_separate(len, data, ...)rustbuffer_freeffi_zx_document_ffi_rustbuffer_free_separate(capacity, len, data)待修复
剩余约 10 个函数仍用旧 struct-passing(
pushReadingEvent、readTextStats、readImageMeta、detectMaterialType、searchMarkdownBlocks、searchTextContent、updateReadingPosition、exportPendingEvents、createNoteAnchor、clearExportedEvents、parseText)临时影响
iOS
MaterialReaderView.onAppear中 collector 调用已注释(因pushReadingEvent仍用旧 API 会 crash)状态
🟡
parseMarkdown路径已修复并验证通过,剩余函数待下一轮集中转换。关闭
ARM64 ABI 已修复 — out-pointer _separate 函数实现