« makeの代わりにGradleを使ってみる | トップページ | 「氷菓」を読んで »

2016年12月11日 (日)

C言語からGo言語へコールバック登録する(Go 1.7.4)

Go言語でプログラミングするのは楽だな。。
と今だけ思ってる。
だけど、いろいろやろうとすると、
どの言語でもあるけど、面倒だなぁ。

C言語は使う時が多いので、
Go言語でC言語のライブラリを作ろうとしてみた。

簡単に呼ぶならできそうだったので、
C言語からコールバックを登録して、
Go言語から折り返す。

主にポインタとかポインタとか、ポインタがつらい。
C言語だと全部ポインタで、通るけど、
Go言語はそれより型がきっちりしている印象が出た。
夢のポインタ (void*)さんがない影響かな。


まず、C言語から呼ぶとか、Go言語から呼ぶは、
どうにかなりそうな感じだった。

The Go Programming Language
Command cgo

CからGo言語を呼ぶ場合は、
「C references to Go」にあるように、
exportってキーワードを使えば、C言語用のヘッダファイルも出してくれる。
C用のライブラリにするのは、こんなコマンド。

go build -buildmode=c-archive hogehoge.go

反対にGo言語からC言語を呼ぶ場合、
「Go references to C」にあるように、
ブリッジ用のメソッドをGo言語側に用意する必要があるようだった。
fortytwo がC言語側で定義されてるイメージになる例。

これを組み合わせると、何故かトラップが発生する。

メソッドに、export を指定すると、どうも、
import "C" より上のメソッドもC言語向けヘッダに出力される。
そのあとに、C言語向けのヘッダを読むようで、
重複定義になってしまう。

だから、exportを指定するGoファイルでは、
C言語用関数の実体は書けないみたい。
staticにすれば、いいみたいだけど、
それもヘッダに出ちゃってる。


そんなこんなで、
C言語からコールバックを指定するような場合、
export するGoファイルと、
ブリッジの実体を書くGoファイルを分ける必要があるみたい。

実体を書くだけで、
重複とエラーが出るので、
かなりわかりづらいけど、
今のcgoの仕様なのかな。

githubのcgoの
Function pointer callbacks

には、そんな例になってるので、
これが正解なんだろうな。

わかるまでは大変だな。
そして、どの言語も罠があるもんだな。


|

« makeの代わりにGradleを使ってみる | トップページ | 「氷菓」を読んで »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/97274/68804227

この記事へのトラックバック一覧です: C言語からGo言語へコールバック登録する(Go 1.7.4):

« makeの代わりにGradleを使ってみる | トップページ | 「氷菓」を読んで »