LoginSignup
26
23

More than 5 years have passed since last update.

Go 1.6 でポインタをcgoの関数へ渡す際の注意点

Last updated at Posted at 2016-01-24

一次ソースはこちら→ https://github.com/golang/proposal/blob/master/design/12416-cgo-pointers.md そのうち誰かが訳してくれると信じています

前提

  • この記事では、Goで確保されたメモリへのポインタをGoポインタとする1
  • この記事を書いている時点では、Go1.6はbeta2のため、まだ変わるかもしれない
  • Goで確保されたメモリはGCされたり、将来的には自動で移動するようになるかもしれない2
  • C側で確保されたメモリはGCされない。将来的な自動移動も行われない

Go1.6からどうなるか

  • Goポインタをcgoの関数へ引数として渡すと、そのcgoの関数から返ってくるまでそのポインタが指すメモリは保護3されGCされたり移動したりしなくなる

そのため、下記の点を注意する必要があります

  • cgoの関数の引数経由以外の方法でGoポインタをCに渡した場合は、そのGoポインタが指すメモリは保護されない
  • cgoの関数から返ってくると保護されていたGoポインタの保護も外れるため、cgoの関数内でGoポインタをどこかに保存して次に呼ばれたcgoの関数内で再利用とかはできない
  • GoポインタへのGoポインタをcgoの関数に渡すのは基本ダメ
    • 保護されるのは引数で渡されたGoポインタが指す先のみで、その指す先の更に指す先は保護されない
    • go1.6beta2では、cgo関数呼び出し時のチェックに引っかかってcgo argument has Go pointer to Go pointerというエラーメッセージが表示される
    • Cで確保されたメモリへのポインタへのGoポインタならOK。Cで確保されたメモリはGC対象ではないため
  • GoポインタへのGoポインタがダメなのと同じ理由で、Goポインタをフィールドに持つ構造体へのGoポインタをcgoに渡すのも基本ダメ


  1. こちらで定義されているのの直訳→ we define a Go pointer to be a pointer to Go memory 

  2. 自動で移動するようになるかもって書いてある→ If a later garbage collector implements moving pointers, 

  3. be pinnedと書いてある箇所を「保護」と訳しました。こちら参照→ https://github.com/golang/proposal/blob/a3c90bbfd94cdec0c55c97d320e6707c64ac9f64/design/12416-cgo-pointers.md#consequences 

26
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
23