CGO を使用して関数ポインタを C コードに渡す
概要
以前の Go バージョン1.6 では、CGO を使用して関数ポインタを C コードに渡すのは簡単でした。ただし、Go 1.6 での新しいルールの導入により、この慣行はより複雑になりました。
問題
問題の核心は、更新された CGO ルールにありますこれは、参照するメモリに他の Go ポインターが含まれていない場合、Go コードは Go ポインターを C にのみ渡すことができると規定しています。関数ポインタは他の Go ポインタを含む可能性のある Go メモリに保存されるため、問題が発生します。
考えられる解決策
この問題に対処するために、いくつかのアプローチが登場しています。一般的な解決策の 1 つは、直接関数ポインターの使用を完全に放棄することです。代わりに、ID (整数) を実際の関数ポインターにマップする同期データ構造を作成します。これにより、ポインター自体ではなく ID を C コードに渡すことができます。
実装例
次のコード スニペットは、このアプローチの実装方法を示しています。
<code class="golang">package gocallback import ( "fmt" "sync" ) type Callback func(C.int) var mu sync.Mutex var index int var fns = make(map[int]Callback) func register(fn Callback) int { mu.Lock() defer mu.Unlock() index++ for fns[index] != nil { index++ } fns[index] = fn return index } func lookup(i int) Callback { mu.Lock() defer mu.Unlock() return fns[i] } func unregister(i int) { mu.Lock() defer mu.Unlock() delete(fns, i) }</code>
C コードでの使用法
Go データ構造が整ったら、関数ポインタではなく ID を渡すことで、C コードから Go コールバックを呼び出すことができます。自体。例:
<code class="c">extern void go_callback_int(int foo, int p1); static inline void CallMyFunction(int foo) { go_callback_int(foo, 5); }</code>
結論
新しい CGO ルールにより、関数ポインターを C コードに渡すプロセスが若干複雑になりますが、この記事で概説するアプローチは、効果的なソリューションを提供します。同期されたデータ構造と ID を活用することで、最新の CGO 規制を遵守しながら、Go コードと C コード間のインターフェイスの利点を引き続き享受できます。
以上がGo バージョン 1.6 以降で CGO を使用して関数ポインターを C コードに渡すにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。