どうも、たくチャレ(@takuchalle)です。

GO 言語から C 言語の関数を呼ぶ方法は調べたらすぐ出てくるのに逆は全然出てこなかったので、備忘録として残しておきます。

手順

  1. Cをインポートする
  2. C 言語から呼びたい関数に//export XXXXを書く
  3. コンパイルする

具体的に解説します。 hoge.goというファイル名のPrintHoge関数を C 言語から呼べるようにします。

package main

import (
    "C"
    "fmt"
)

//export PrintHoge
func PrintHoge() {
    fmt.Println("hoge")
}

func main() {}

main関数がないとエラーになるので、空で良いので書いておきます。

-buildmode=c-archiveオプションをつけてgo buildします。

$ go build -buildmode=c-archive hoge.go

すると、hoge.aアーカイブとhoge.hヘッダが生成されます。

生成されたヘッダをインクルードして、Go 言語の関数を呼びます。

#include <stdio.h>
#include "hoge.h"

int main() {
    PrintHoge();
    return 0;    
}

生成されたアーカイブと一緒にコンパイルします。

$ gcc -o hoge hoge.a main.c
$ ./hoge
hoge

注意

C 言語から呼びたい関数の引数にはプリミティブな型しか指定できないです。

intは指定できますが、

//export PrintHoge
func PrintHoge(i int) {
        fmt.Println(i)
}

io.Readerは指定できません。

//export PrintHoge
func PrintHoge(r io.Reader) {
        ....
}

下記のようなエラーが出ます。

# command-line-arguments
./hoge.go:10:18: Go type not supported in export: io.Reader

誰かの参考になったら嬉しいです。