C 言語のプログラムから Go で書いた関数を呼ぶ的なことをやってみたくていろいろと試行錯誤してたけどようやくうまくいったのでポイントをメモします。
コンパイラは gcc 4.7.2 です。
あくまで自分のやったことのメモなので正しい方法ではないかもですが、超五里霧中で進んでいる感じなのでどのような指摘も大歓迎しております。
ポイント 1. darwin を見捨てる
俺の環境の問題かもしれないけど OSX 上で Go 言語サポート付きで gcc 4.9 を入れて、普通に Go で Hello world を書いてみてコンパイルしてみてもうまく動かない、というか生成されるアセンブリがなんかおかしいということで割と早速手に負えない感じなので早々に見捨てました。
つーことで Debian wheezy です。
ポイント 2. Go 言語側にダミーのエントリポイントを作っておく
Go 言語側ではどうあっても main.main を要求されてしまったので、数時間にわたる熟考の結果、「とりあえず main 関数定義しておくか」という一番最初に思いついた安易な対処方法であっさり動いた。もうこれでいいや。
ソースコード
https://github.com/ebihara/test-go-in-c-with-gccgo
こちらになります。
Go 言語サポート付きの gcc を導入済みの状態で make すれば main が生成されるので、それを実行すると Hello from C lang and Hello from Go!! とか出てくるはずです。
出力部分のコードは main.c にあります:
printf("Hello from C lang and %s!!\n", go_hello());
で、この go_hello() で Go 言語側で定義した関数をコールしているわけですが、 extern 部分でインラインアセンブラとか使っててひぃぃぃって感じなんですがこれしかなさそう。というかこれが gcc 的にオフィシャルのようなので……
なお、 Go 言語側は普通なので特筆するべきポイントはありません。
ということで数週間くらいチビチビやっていて、やっとやりたいことの入り口に立てた感じなのですが、えーっと gccgo だと Go 言語側の GC の機構が使えないとかなんとかを見かけたりした記憶があるのですが、あれ、でも古い情報かもしれないしなーってことで gccgo での制限事項とか調べはじめないとなってところです。
そもそも Go はド素人なので言語仕様自体の勉強もしつつやっていかないといけないんですけど、まあ、極力 C を書かなきゃいけない機会を減らしたいのでそういう未来のために頑張っていきたい所存です。