2018年12月1日土曜日

cgo 入門

概要

cgo は golang に含まれている C のライブラリを扱うためのパッケージです
今回は使い方とポイントを入門レベルで紹介します

環境

  • macOS 10.14.1
  • golang 1.11.2

とりあえず動かす

  • mkdir -p $GOPATH/github.com/hawk/cgo_test
  • vim $GOPATH/github.com/hawk/cgo_test/main.go
package main

/*
#include <stdio.h>
void Cprint(char* str) {
  printf("%s", str);
}
*/
import "C"

func main() {
    str := C.CString("hoge\n")
    C.Cprint(str)
}
  • go build github.com/hawk/cgo_test
  • go install github.com/hawk/cgo_test
  • cgo_test

hoge と表示されるはずです
ポイントは import "C" 直前に C 言語を使った関数を定義しているところです
ここで定義した関数は C.Cprint という感じで C.hoge という形式で参照することができます
また CString のように cgo によりすでに用意されている関数もあります
CString は golang の世界の String 型を C 言語の世界の char* に変換してくれる関数です

C の標準ライブラリ

こちらが参考になると思います
基本的にはここにあるライブラリを cgo を使って使えるようになります

返り値を使う

  • vim $GOPATH/github.com/hawk/cgo_test/main.go
package main

/*
#include <math.h>
double MyPow(double x, double y) {
  double ret = pow(x, y);
  return ret;
}
*/
import "C"
import "fmt"

func main() {
    ret := C.MyPow(10, 2);
    fmt.Println(ret);
}

これを実行すると普通に 100 と表示されます
ただ、型を見ると main._Ctype_double になっていました
四則演算などはそのままできましたが必要に応じて型を変換しないと使えない可能性はありそうです

マクロの呼び出し

  • vim $GOPATH/github.com/hawk/cgo_test/main.go
package main

/*
#define MSG "Hello"
#define ADD(a, b) (a + b)
int Add(int a, int b) {
  int ret = ADD(a, b);
  return ret;
}
*/
import "C"
import "fmt"

func main() {
    ret := C.MSG
    fmt.Println(ret);
    ret2 := C.Add(10, 10);
    fmt.Println(ret2);
}

引数ありの関数として定義しているマクロは直接呼べないようです
以下のエラーが発生しました

could not determine kind of name for C.ADD

もしかしたら呼べる方法があるかもしれません
確実なのは関数を定義してその中でマクロ関数をコールするようにすると呼べます

最後に

cgo の簡単な使い方を紹介しました
他の言語と比べるとデフォルトでそのまま使えてかつ簡単に C 言語の標準ライブラリが参照できるのが嬉しい点かなと思います

C 言語の他の機能 (struct や pointer など) は検証していませんが使えるとは思います
基本的には C 言語の共有ライブラリ形式で提供されている関数を使いたい場合などに cgo で連携する感じが一般的な使い方なのかなーと思います

参考サイト

0 件のコメント:

コメントを投稿