ワテのブログ

The fundamental things apply As time goes by.

2014年7月31日木曜日

[golang] cgoの使い方

スポンサーリンク

ファイル構成

$ ls
test.c  test.go  test.h

goからc/c++の関数を呼び出す。
c/c++からgoの関数を呼び出す方法。
import “C”の真上のコメントがCの定義部として処理されます。
そこで定義されているものはgoの世界から”C.”プリフィックスでアクセスできます。
C.GoStringはcの文字列からgoの文字列を生成します。
C.CStringはgoの文字列からc文字列を生成します。mallocでメモリが確保されるのでfreeで解放する必要があります。

goの関数は関数上に//export 関数名と書くことで_go_export.hに書きだされます。
c側で
#include “_cgo_export.h”
としてやれば呼び出すことができます。
関数の戻り値は関数名_returnという構造体が自動的に定義されます。

$ go tool cgo test.go

で_objフォルダにcのコードが吐出されます。
こいつの中をみれば理解しやすいでしょう。
ちなみにc++のコードを呼ぶときは関数の宣言をextern “C” {}で囲ってやればよろしい。

関連項目

// test.go
package main

/*
#include "test.h"
*/
import "C"
import (
    "fmt"
    "unsafe"
)

//export gohoge
func gohoge(h *C.hoge_t) (C.int, *C.char) {
    fmt.Printf("go -> %d:%s\n", h.a, C.GoString(h.str))
    return 2, C.CString("return from go")
}

func main() {
    h := &C.hoge_t{
        a:   C.int(1),
        str: C.CString("hello from go"),
    }
    C.hoge(h)
    C.free(unsafe.Pointer(h.str))
}
// test.h
#ifndef test_h
#define test_h
#include <stdio.h>
#include <stdlib.h>

typedef struct hoge_t {
  int a;
  char *str;
} hoge_t;

extern void hoge(hoge_t* h); 
#endif
// test.c
#include "test.h"
#include "_cgo_export.h"

void hoge(hoge_t* h) {
  struct gohoge_return r = gohoge(h);
  fprintf(stdout, "c  -> %d:%s\n", r.r0, r.r1);
  free(r.r1);
}
# 実行結果
go -> 1:hello from go
c  -> 2:return from go
スポンサーリンク

0 件のコメント:

コメントを投稿