Skip to main content
ArkFFI 在 TypeScript 層管理部分記憶體,但大多數情況下 C 庫的記憶體由 C 庫自身管理。理解各場景的記憶體歸屬,可避免泄漏和野指針。

概覽

基本類型傳參

intdoublechar 等基本類型透過暫存器或堆疊傳遞,不涉及任何記憶體分配。直接傳入即可。

字串傳參

當參數類型為 FFIType.CString 時,NAPI 層會用 napi_get_value_string_utf8 取得 C 字串,在堆上分配 char*,呼叫 C 函數後立即 delete[]。使用者無需管理。

字串回傳值

callString 回傳 C 庫內部持有的 const char*,ArkFFI 只讀取其內容(napi_create_string_utf8),不分配也不釋放。指針的生命週期由 C 庫管理。 結構體 fromPtrconst char* 欄位同樣回傳指針數值,該指針指向 C 庫記憶體,不要透過 releasePtr 釋放

結構體傳參

透過 StructSchema.create() 建立的 ArrayBuffer 由使用者分配,傳遞給 C 函數後由使用者自行管理其生命週期。

結構體回傳值(releasePtr

dlopen / CFunctionreturnsStructSchema 時,ArkFFI 內部會:
  1. 呼叫 NAPI 取得 ArrayBuffer
  2. 透過 ffi.ptr 取得其資料指針
  3. ArrayBuffer 存入 g_structResults Map 防止 GC
  4. 回傳指針給使用者
使用者透過 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.ptrFFIType.callback 傳達的是位址值(number),不涉及記憶體分配。位址由 C 庫管理或由 JSCallback 內部槽位管理。

核心原則

ArkFFI 只管理自己分配的記憶體。C 庫的記憶體由 C 庫管理。