2012-03-02 21 views
10

E 'possibile rendere il garbage collector in Go handle e rilasciare la memoria allocata attraverso il codice C? Mi scuso, non ho usato C e cgo prima, quindi i miei esempi potrebbero richiedere qualche chiarimento.Garbage collection e cgo

Diciamo che hai una libreria C che vorresti usare e questa libreria alloca parte della memoria che deve essere liberata manualmente. Quello che mi piacerebbe fare è qualcosa di simile:

package stuff 

/* 
#include <stuff.h> 
*/ 
import "C" 

type Stuff C.Stuff 

func NewStuff() *Stuff { 
    stuff := Stuff(C.NewStuff()) // Allocate memory 

    // define the release function for the runtime to call 
    // when this object has no references to it (to release memory) 
    // In this case it's stuff.Free()  

    return stuff 

} 

func (s Stuff) Free() { 
    C.Free(C.Stuff(s)) // Release memory 
} 

C'è un modo per il garbage collector per chiamare Stuff.Free() quando non ci sono riferimenti a * roba in runtime Go?

Ho un senso qui?

Forse una domanda più diretta è: è possibile rendere il runtime gestire automaticamente la pulizia della memoria allocata C scrivendo una funzione che il runtime chiama quando ci sono riferimenti zero a quell'oggetto?

risposta

12

Esiste la funzione runtime.SetFinalizer, ma non può essere utilizzata su alcun oggetto assegnato dal codice C.

Tuttavia, è possibile creare un oggetto Go per ogni oggetto C che ha bisogno di essere liberata automaticamente:

type Stuff struct { 
    cStuff *C.Stuff 
} 

func NewStuff() *Stuff { 
    s := &Stuff{C.NewStuff()} 
    runtime.SetFinalizer(s, (*Stuff).Free) 
    return s 
} 

func (s *Stuff) Free() { 
    C.Free(s.cStuff) 
}