2014-02-24 43 views
1

想,我有一個C庫OCaml的接口:OCaml的垃圾收集幻象類型

type _npnum;; 

    external _create_zero : int -> int -> _npnum = "ocaml_tnp_number_create_zero" ;; 

    external _delete : _npnum -> unit = "ocaml_tnp_number_delete" ;; 

的C-庫分配的對象,並通過OCaml中的的Int32/64表示返回他們(我「偷」,從ctypes的)。

但其實我是想OCaml的垃圾收集這些物品,所以我怎麼告訴編譯器/運行時_delete將用於清理一個_npnum

我試圖將整個事情包裝到一個記錄中,並使用Core的終結器函數,但這是一種不需要的依賴關係,只有在沒有人複製記錄時才起作用。我想有一個更好的解決方案?

回答

1

在標準庫中有Gc.finalise,如果你的數據類型是抽象的,大多數情況下沒有人應該能夠複製它(但是正如Pascal在下面正確指出的那樣,有幾個例子)。

如果您確實想要處理這些轉角情況,請在C大小上使用custom block來包裝指針並將其作爲抽象類型公開。這將允許您附加自定義終結器,正確處理編組並且Weak.get_copy不會嘗試複製它。

+0

可以使用'Weak.get_copy'和各種解組函數來複制抽象對象。我不知道'Gc.finalise'如何與'Weak.get_copy'結合。 –

+1

看看[實施](https://github.com/ocaml/ocaml/blob/trunk/byterun/weak.c)它沒有做任何特別的事情。但由於它做了一個淺拷貝,你應該可以通過做'type wrap = {v:_npnum}'(finalized value)'type t = {wrap:wrap}'並暴露't'。 –

+0

爲什麼沒有人能夠複製我的抽象數據類型?當我公開它時,肯定可以編寫一個函數,該函數需要一個'_npnum'並將它傳遞給兩個或更多其他函數,因此將其複製? – choeger