はじめに
Go 1.6 では変更が導入されましたcgo を介して C コードにポインタを渡すためのルール。その結果、C コードから動的 Go コールバックを呼び出すために以前は実行できたメソッドは機能しなくなります。この記事では、更新されたガイドラインを検討し、現在の Go エコシステムで関数ポインターを C コードに効果的に渡す方法を示します。
Go 1.6 で関数ポインターを渡す
Go から始める1.6 では、次のルールが適用されます。
Go コードが指す Go メモリに Go ポインターが含まれていない場合、Go コードは Go ポインターを C に渡すことができます。
この制限は実行時チェックに起因します。違反を監視し、検出された場合はクラッシュを引き起こします。環境変数 GODEBUG=cgocheck=0 を設定すると、これらのチェックは一時的に無効になりますが、将来の Go バージョンでは削除される可能性があります。
結果と解決策
新しいルールによりパスが禁止されます指すメモリが Go 関数/メソッド ポインタを保持している場合は、C コードへのポインタ。この制限を回避するには、いくつかのアプローチが存在します。
同期と ID の対応
1 つの戦略には、ID を実際のポインターにマップする同期されたデータ構造を維持することが含まれます。直接ポインターの代わりに ID を C コードに渡すことで、目的の機能を実現しながら制限を回避できます。
コード例
次のコード スニペットは、次の方法を示しています。このアプローチを実装します:
<code class="go">import ( "fmt" "sync" ) var mu sync.Mutex var index int var fns = make(map[int]func(C.int)) func register(fn func(C.int)) int { mu.Lock() defer mu.Unlock() index++ for fns[index] != nil { index++ } fns[index] = fn return index } func lookup(i int) func(C.int) { mu.Lock() defer mu.Unlock() return fns[i] }</code>
このコードは、Go 関数に一意の ID を割り当て、スレッドセーフな方法でマッピングを保存するレジストリ システムを定義します。 C コードを呼び出すときは、関数ポインタの代わりに ID を直接渡すことができます。
結論
Go 1.6 の変更により、関数ポインタを C に渡すときに慎重な考慮が必要になります。コード。上記のような同期手法を採用することで、新しい制限を効果的に克服し、Go の最新バージョンとの互換性を確保できます。
以上が新しい制限がある場合、Go 1.6 で関数ポインタを C コードに渡すにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。