GoのコードからCの関数を利用するには、cgo という仕組みを使います{{Cite web
|url=https://pkg.go.dev/cmd/cgo
|title=cgo command - cmd/cgo - pkg.go.dev
|date=2021/11/04
|accessdate=2021/11/29
。
Cの標準ライブラリー関数に、整数で分子と分母を与えると商と剰余を返す関数 div() があります。
Goの多値返しと似ているので、Goから呼べるようにしてみました。
Cの標準ライブラリー関数 div() をGoから呼出せるようにした例:
package main
import (
        //#include 
        "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 
"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型に変換します。