【Go言語学習|初心者向け】GoのコードをC言語から呼び出す!c-archiveによるライブラリ化入門

1. 導入

Go言語は高速で並行処理に優れていますが、既存のC言語プロジェクトや、特定のOS向けに最適化されたCアプリケーションで「Goの強力なライブラリ機能を使いたい」という場面がしばしばあります。そんな時に役立つのが、Goのプログラムを静的ライブラリ(.aファイル)として書き出す「c-archive」という機能です。これを使えば、GoのコードをC言語のモジュールとして組み込み、既存のレガシーシステムをモダンなGoの機能で拡張することが可能になります。

2. 基礎知識

通常、Goで作成したプログラムは単体で実行可能なバイナリとして生成されます。しかし、GoにはC言語と相互運用するための「cgo」という仕組みが備わっています。
今回紹介する「-buildmode=c-archive」は、Goの関数をCから呼び出せるようにコンパイルし、静的ライブラリ(.aファイル)と、その定義が書かれたヘッダーファイル(.hファイル)を生成するビルドモードです。

3. 実装/解決策

Goの関数をCから呼び出すには、以下の手順が必要です。
1. Goコードの冒頭で「import “C”」を記述する。
2. 公開したい関数に「//export 関数名」という特殊なコメントを付与する。
3. mainパッケージで記述する(main関数は空でも良い)。
4. go build -buildmode=c-archive コマンドでビルドする。

4. サンプルプログラム

まずは、Go側のコード(libmath.go)を作成します。

package main

import “C”

//export Add
// Add関数は、C言語から呼び出せるようにエクスポートされます
func Add(a, b int) int {
return a + b
}

// main関数は空でも必要です
func main() {}

次に、ターミナルで以下のコマンドを実行してビルドします。

go build -buildmode=c-archive -o libmath.a libmath.go

これで「libmath.a」と「libmath.h」が生成されます。次に、これを利用するC言語側のコード(main.c)を作成します。

include
include “libmath.h” // 生成されたヘッダーを読み込む

int main() {
// Goで定義したAdd関数を呼び出します
int result = Add(10, 20);
printf(“Goで計算した結果: %d\n”, result);
return 0;
}

最後に、コンパイルして実行します。

gcc main.c libmath.a -o myapp
./myapp

5. 応用・注意点

この手法を用いる際、いくつか注意すべき点があります。

型変換の注意: GoとC言語の間で複雑なデータ構造(構造体やポインタ)を渡す際は、メモリ管理に注意が必要です。Goのガベージコレクタが管理するメモリをC側で解放しようとするとクラッシュの原因になります。可能な限り、単純な数値型や固定長の配列でやり取りすることをおすすめします。
ビルド環境: cgoを利用するため、ビルド環境にはCコンパイラ(gccなど)がインストールされている必要があります。
クロスコンパイル: c-archiveはターゲット環境ごとのCコンパイラが必要になるため、通常のGo単体でのクロスコンパイルよりも環境構築の難易度が上がります。

Goの資産をC言語の世界へ持ち込むことで、システムの再利用性が劇的に向上します。ぜひ、既存のプロジェクトで試してみてください。

コメント

タイトルとURLをコピーしました