だいぶ時間が掛かった様ですが、ようやく buildmode=c-archive
が Windows でも使える様になりました。
cmd/go: -buildmode=c-archive should work on windows · Issue #13494 · golang/go · GitHub
32-bit is also important to me. I'd like to help. I'm seeing those same link errors when I enable it...
https://github.com/golang/go/issues/13494
まだ buildmode=c-shared
(いわゆる dll) はビルド出来ないけど、ひとまずC言語から golang のライブラリをリンクして動かせる様になりました。例えばこんな事が出来ます。
package main
import "C"
import (
"fmt"
"github.com/mattn/go-haiku"
)
var (
q = make(chan string)
)
func init() {
go func() {
for {
fmt.Println(<-q)
}
}()
}
//export PrintHello
func PrintHello(p *C.char) {
q <- C.GoString(p)
}
//export IsHaiku
func IsHaiku(p *C.char) C.int {
var ret C.int
if haiku.Match(C.GoString(p), []int{5, 7, 5}) {
ret = 1
}
return ret
}
//export PrintLine
func PrintLine(p *C.char) {
fmt.Println(C.GoString(p))
}
func main() {
}
この様なソースコード lib.go
を用意し以下の手順で lib.a
を作ります。
go build -buildmode=c-archive lib.go
そしてC言語からは以下の様に呼び出します。
#include <stdio.h>
int
main(int argc, char* argv[]) {
extern void PrintHello(char*);
PrintHello("hello");
PrintHello("hello");
PrintHello("hello");
PrintHello("hello");
PrintHello("hello");
Sleep(3000);
return 0;
}
ビルドは以下の様になります。
gcc -o example.exe example.c lib.a -lws2_32 -lntdll
goroutine と channel を使っているので PrintHello
の呼び出しは非同期に画面出力されます。golang では簡単に扱えるけどC言語だと若干手間だなと思える様な処理もリンクするだけで使える様になります。以下は ikawaha さんの kagome を使って俳句を扱えるライブラリ go-haiku をC言語から呼び出しています。
#include <stdio.h>
int
main(int argc, char* argv[]) {
extern void PrintLine(char*);
extern int IsHaiku(char*);
char* s = "古池や蛙飛び込む水の音";
PrintLine(s);
if (IsHaiku(s)) {
PrintLine("それ575じゃん");
}
return 0;
}
古池や蛙飛び込む水の音
それ575じゃん
めちゃめちゃ簡単ですね。