Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

一次ソースはこちら→ 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 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away