ホームページ  >  記事  >  バックエンド開発  >  謎のエラー: 「cgo 引数への Go ポインタが固定されていない Go ポインタを指している」

謎のエラー: 「cgo 引数への Go ポインタが固定されていない Go ポインタを指している」

PHPz
PHPz転載
2024-02-06 10:48:04658ブラウズ

神秘错误:“cgo 参数的 Go 指针指向未固定的 Go 指针”

質問内容

このエラーが発生し、ドキュメントを読んでも意味がわかりません。実際、私はそれを理解していると思っていましたが、それが私に起こった方法には当てはまりませんでした。この特定の問題に関する他の情報はインターネット上の他の場所にはないようです。

私にとって、それはこの関数で発生します (私のライブラリではなく、多くの場所で正常に動作するようですので、それはさらに奇妙です)。

エラーをよりよく理解するために、C 関数の各パラメーターが個別に構築されるようにローカルで変更し、どの部分がエラーを引き起こしたかを確認しました。

しかし、カーソルの下の行でエラーが発生していることが判明したため、これは完全に

C.lmdbgo_mdb_cursor_get1() 呼び出しに関連していると思います。

このエラーは、Go ポインタを C 関数に渡していることを意味しており、Go ポインタを

unsafe.Pointer() 呼び出しでラップすることで回避できると思いましたが、それは不可能ですCompletion がすでに存在し、関連する C 関数へのすべての引数がすでに Go 型ではなく C 型であるためです。

更新: さらに詳しく調べたところ、実際の panic()/src/runtime/cgocall.go の 689 行目で発行されていることがわかりました。の:### したがって、

cgoIsGoPointer()

true を返し、isPinned() は false を返します。 Go ポインタを「修正」するにはどうすればよいですか?それとも、これは間違った質問ですか?

更新:

さらに調査した結果、問題の原因となっているパラメータは c.txn.key であることがわかりました。これは私の制御の範囲を超えており、 に設定されているようです。新しい (C.MDB_val)

正解


https://github.com/PowerDNS/lmdb-go/issues /28

によると、この質問は実際に提起されましたGo new() コンストラクターを使用して C ポインターを作成し、それを C 関数に渡すことが原因で発生します。これらは C.malloc() を使用して作成する必要があります。 どうやら、この問題は他の誰にも現れていないようです。なぜなら、このライブラリを使用したときに私が犯した同じ間違いを誰も犯していないからです。複数のゴルーチンから同じトランザクションを使用することです。これは、LMDB によって明示的に禁止されています (まあ、LMDB はスレッドと言っていますが、おそらく私のゴルーチンが新しいスレッドを生成している可能性があります)。

wojas

: によると

以上が謎のエラー: 「cgo 引数への Go ポインタが固定されていない Go ポインタを指している」の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はstackoverflow.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。