ホームページ >バックエンド開発 >Golang >C 文字列の配列へのポインターを期待する C 関数に Go スライスを渡すにはどうすればよいですか?

C 文字列の配列へのポインターを期待する C 関数に Go スライスを渡すにはどうすればよいですか?

DDD
DDDオリジナル
2024-12-11 10:20:16242ブラウズ

How Can I Pass a Go Slice to a C Function That Expects a Pointer to an Array of C Strings?

スライスへのポインタを Go の C 関数に渡す

Go では、C 関数と対話するときの一般的なタスクは、複雑な関数を渡すことです。スライスなどのデータ構造。ただし、Go スライスと C 配列には、特別な処理を必要とする根本的な違いがあります。

シグネチャ int f(int *count, char ***strs) を持つ次の C 関数を考えてみましょう。これには 2 つのポインタが必要です。count は文字列の配列の長さを指し、strs は文字列ポインタの配列を指します。

Go では、スライスは次のような関数であるため、そのような関数に直接スライスを渡すことはできません。 Go 固有のデータ構造であり、C 配列とは異なります。さらに、Go スライスには Go ポインタが含まれており、cgo は C 関数に渡すことを禁止しています。

これを克服するには、C で配列を手動で割り当て、外側の配列を解放する場所を追跡する必要があります 。 Go スライス内の各文字列について、C.CString を使用してC 文字列に変換し、割り当てられた C 配列に対応する C 文字列ポインタを記録します。

Go コードの修正バージョンは次のとおりです。

cArray := C.malloc(C.size_t(c_count) * C.size_t(unsafe.Sizeof(uintptr(0))))

// Convert the C array to a Go Array for easy indexing
a := (*[1<<30 - 1]*C.char)(cArray)
for index, value := range strs {
    a[index] = C.CString(value)
}

err := C.f(&c_count, (***C.char)(unsafe.Pointer(&cArray)))

このアプローチにより、C 関数が確実にアクセスできるようになります。操作可能な C 配列を使用すると、操作された配列をさらに使用するために Go スライスに変換し直すことができます。

以上がC 文字列の配列へのポインターを期待する C 関数に Go スライスを渡すにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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