私はGoライブラリ(gofileseq)を所有しています。そのためにC/C++バインディングを試してみたいと思います。複雑なGo構造体をCにエクスポート/ラップすることはできますか?
単純な型(int、文字列など)を使用する関数をエクスポートするのはかなり簡単です。 Cの構造体を定義し、Goの型をそれに変換することで、エクスポートされた関数で使用するためにCのメモリを割り当てるので、カスタムのGo型からCにデータをエクスポートするだけでも簡単です。しかし、go 1.5 cgo rulesでは、状態を格納するより複雑な構造体から機能をエクスポートする方法を理解するのは難しいと感じています。私はC++バインディングに何とかエクスポートしたいgofileseqから構造体の
例:
// package fileseq
//
type FrameSet struct {
frange string
rangePtr *ranges.InclusiveRanges
}
func NewFrameSet(frange string) (*FrameSet, error) {
// bunch of processing to set up internal state
}
func (s *FrameSet) Len() int {
return s.rangePtr.Len()
}
// package ranges
//
type InclusiveRanges struct {
blocks []*InclusiveRange
}
type InclusiveRange struct {
start int
end int
step int
cachedEnd int
isEndCached bool
cachedLen int
isLenCached bool
}
あなたが見ることができるように、私は公開したいFrameSet
タイプは、基礎となるまでのポインタのスライスが含まれていますそれぞれ、状態を格納する。
void*
をC++クラスに格納し、エクスポートされたGo関数をvoid*
で呼び出すための単純なプロキシーにすることが理想的です。しかしcgoルールは、関数呼び出しよりもGoポインタを格納していないCを許可しません。そして私はGoライブラリを使って動作するために割り当てられ使用されるC++クラスを定義するアプローチをどのように使うことができないのか見当ろうとしていません。
C/C++へのエクスポージャーのために複合型をラップすることはできますか? C++クライアントがGo FrameSet
を作成するためのパターンがありますか?
編集私はC++が静的map[int]*FrameSet
に行く側に保存されて取りに行くにオブジェクトを作成し、C++にint型のIDを返すようにするだろうと考えることができ
ひとつのアイデア。その後、すべてのC++演算がidにGoを要求します。それは有効な解決策のように聞こえるか?
更新
今のところ、私は、オブジェクトを格納するグローバルマップと固有のIDを使用してソリューションのテストを進めています。 C++は新しいオブジェクトの作成を要求し、不透明なIDのみを取得します。そして、そのIDを使用して、関数としてエクスポートされたすべてのメソッドを呼び出すことができます(完了時に破棄することを要求するなど)。
これよりも優れたアプローチがある場合は、私は答えを見たいと思います。完全に動作するプロトタイプを取得したら、私自身の答えを追加します。
アップデート#2
私は私が使用して終了し、最終的な解決策についてのブログ記事を書いた:http://justinfx.com/2016/05/14/cpp-bindings-for-go/