概覽
基本類型傳參
int、double、char 等基本類型透過暫存器或堆疊傳遞,不涉及任何記憶體分配。直接傳入即可。
字串傳參
當參數類型為FFIType.CString 時,NAPI 層會用 napi_get_value_string_utf8 取得 C 字串,在堆上分配 char*,呼叫 C 函數後立即 delete[]。使用者無需管理。
字串回傳值
callString 回傳 C 庫內部持有的 const char*,ArkFFI 只讀取其內容(napi_create_string_utf8),不分配也不釋放。指針的生命週期由 C 庫管理。
結構體 fromPtr 中 const char* 欄位同樣回傳指針數值,該指針指向 C 庫記憶體,不要透過 releasePtr 釋放。
結構體傳參
透過StructSchema.create() 建立的 ArrayBuffer 由使用者分配,傳遞給 C 函數後由使用者自行管理其生命週期。
結構體回傳值(releasePtr)
當 dlopen / CFunction 的 returns 為 StructSchema 時,ArkFFI 內部會:
- 呼叫 NAPI 取得
ArrayBuffer - 透過
ffi.ptr取得其資料指針 - 將
ArrayBuffer存入g_structResultsMap 防止 GC - 回傳指針給使用者
fromPtr 讀取後,應呼叫 releasePtr 釋放 Map 中的參照,使 ArrayBuffer 可被 GC。
不呼叫 releasePtr 會怎樣?
g_structResults Map 持續持有 ArrayBuffer 的參照,指針始終有效。Map 條目在呼叫 releasePtr 或程式退出前不會被 GC,但一般不構成問題(條目數等於 struct 回傳呼叫次數)。
釋放錯誤指針會怎樣?
releasePtr(ptr) 在 Map 中按 key 查找。如果 ptr 不是由 ArkFFI struct 回傳分配的指針(例如來自 C 庫的 const char*),Map 找不到該 key,靜默無操作,不會崩潰。
指針類型(ptr、callback)
FFIType.ptr 和 FFIType.callback 傳達的是位址值(number),不涉及記憶體分配。位址由 C 庫管理或由 JSCallback 內部槽位管理。
核心原則
ArkFFI 只管理自己分配的記憶體。C 庫的記憶體由 C 庫管理。