ホームページ  >  記事  >  バックエンド開発  >  Go バージョン 1.6 以降で CGO を使用して関数ポインターを C コードに渡すにはどうすればよいですか?

Go バージョン 1.6 以降で CGO を使用して関数ポインターを C コードに渡すにはどうすればよいですか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-11-01 00:01:02704ブラウズ

How can I pass function pointers to C code using CGO in Go versions 1.6 and later?

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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。