11

Go でガベージ コレクターを処理し、C コードを介して割り当てられたメモリを解放することは可能ですか? 申し訳ありませんが、私は以前に C と cgo を使用したことがないため、私の例には説明が必要な場合があります。

使用したい C ライブラリがあり、このライブラリが手動で解放する必要のあるメモリを割り当てているとします。私がやりたいことは次のようなものです:

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
}

Go ランタイムで *Stuff への参照がない場合、ガベージ コレクターが Stuff.Free() を呼び出す方法はありますか?

私はここで理にかなっていますか?

おそらく、より直接的な質問は次のとおりです。そのオブジェクトへの参照がゼロの場合にランタイムが呼び出す関数を作成することにより、ランタイムが C に割り当てられたメモリのクリーンアップを自動的に処理するようにすることは可能ですか?

4

1 に答える 1

14

関数は存在しruntime.SetFinalizerますが、C コードによって割り当てられたオブジェクトでは使用できません。

ただし、自動的に解放する必要がある C オブジェクトごとに Go オブジェクトを作成できます。

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)
}
于 2012-03-02T18:27:45.857 に答える