2012-03-02 6 views
10

Czy można ustawić pojemnik na śmieci w uchwycie Idź i zwolnić pamięć przydzieloną przez kod C? Przepraszam, nie używałem C i cgo, więc moje przykłady mogą wymagać pewnych wyjaśnień.Wyrzucanie śmieci i cgo

Powiedzmy, że masz bibliotekę C, której chcesz użyć, i ta biblioteka przydziela trochę pamięci, która musi zostać zwolniona ręcznie. Co chciałbym zrobić coś takiego:

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 
} 

Czy jest jakiś sposób na śmieciarza zadzwonić Stuff.Free(), gdy nie ma żadnych odniesień do * rzeczy w czasie wykonywania iść?

Czy mam tu jakiś sens?

Być może bardziej bezpośrednie pytanie brzmi: czy możliwe jest automatyczne wykonanie przez środowisko wykonawcze czyszczenia przydzielonej pamięci C przez napisanie funkcji wywoływanej przez środowisko wykonawcze, gdy istnieją zerowe odwołania do tego obiektu?

Odpowiedz

12

Istnieje funkcja runtime.SetFinalizer, ale nie można jej użyć do żadnego obiektu przydzielonego przez kod C.

Można jednak utworzyć obiekt Go dla każdego obiektu C, która musi być zwolniona automatycznie:

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) 
}