Go/cgoでGoのコードからCの関数を利用する
表示
< Go
GoのコードからCの関数を利用するには、cgo という仕組みを使います[1]。
Cの標準ライブラリー関数 div() をGoから呼びさせるようにした例
[編集]Cの標準ライブラリー関数に、整数で分子と分母を与えると商と剰余を返す関数 div() があります。 Goの多値返しと似ているので、Goから呼べるようにしてみました。
- Cの標準ライブラリー関数 div() をGoから呼出せるようにした例
package main import ( //#include <stdlib.h> "C" "fmt" ) // div_t div(int num, int denom); func div(n, d int) (int, int) { divmod := C.div(C.int(n), C.int(d)) return int(divmod.quot), int(divmod.rem) } func main() { for i := 0; i <= 8; i++ { quot, rem := div(i, 3) fmt.Printf("%d / 3: %v .. %v\n", i, quot, rem) } }
- 実行結果
0 / 3: 0 .. 0 1 / 3: 0 .. 1 2 / 3: 0 .. 2 3 / 3: 1 .. 0 4 / 3: 1 .. 1 5 / 3: 1 .. 2 6 / 3: 2 .. 0 7 / 3: 2 .. 1 8 / 3: 2 .. 2
- 解説
"C"
- cgo を使う時は疑似パッケージ "C" をインポートします。
- これで、C.size_tなどの型、C.stdoutなどの変数、C.putcharなどの関数を参照することができます。
- プリアンブル
//#include <stdlib.h>
- "C"のインポートの直前にコメントがある場合、そのコメントはプリアンブルと呼ばれパッケージのC部分をコンパイルする際のヘッダーとして使用されます。
- この場合は div_t型の定義と div()関数の宣言のために、 stdlib.h をインクルードしています。
- Cの関数呼び出し
divmod := C.div(C.int(n), C.int(d))
- Cの div() はGoからは C.div() として呼び出します。このとき引数は C.int のようなCの型に変換する必要があります。
- 戻値の変換
return int(divmod.quot), int(divmod.rem)
- Cに div() は div_t型の戻値を返すので、各メンバーをGoのint型に変換します。
脚註
[編集]- ^ “cgo command - cmd/cgo - pkg.go.dev” (2021年11月4日). 2021年11月29日閲覧。
参考文献
[編集]- `“cgo command - cmd/cgo - pkg.go.dev” (2021年11月4日). 2021年11月29日閲覧。