「Go言語?もうピーク過ぎたよね?」とか言ってる人達こんばんわ。
Go言語、終わってません。いまdev-listではすごい量のメールが飛び交っていて、毎日かなりの量の議論が行われています。
僕としては、ようやく始まったと言えます。もうすぐWindowsでcgoも実行出来る様になります。現在dev-listには既にパッチが投稿されていて、レビュー中です。そろそろ出るんじゃないかと思います。
ただし現状cgoが無いWindowsでもダイナミックローディングが出来ない訳ではありません。syscall.LoadLibraryとsyscall.GetProcAddressを使ってライブラリ関数を取得し、syscall.Syscallで呼び出す事も出来ます。cgo待ってられない!って人でも今すぐDLLを呼び出す拡張モジュールが書けるのです。
今日はその方法を使って、GoからCOM(Component Object Model)を扱えるライブラリを書きました。名前は「go-ole」としました。
mattn/go-ole - GitHub
win32 ole implementation for golang
https://github.com/mattn/go-ole/
GO言語のstructを使って、vtblを作成しています。まぁ先頭ポインタからオフセットでメンバにアクセス出来る言語であれば大体実現出来ますね。
今のところ、プリミティブな型でしか操作出来ません。配列もSAFEARRAYで扱ってません。これからという所です。皆さんのパッチお待ちしています。
サンプルとしてMSAgentでおしゃべりする物が動きました。
go-oleだと以下の様なソースになります。簡単ですね。
package main
import "ole"
import "ole/oleutil"
import "syscall"
func main() {
ole.CoInitialize(0)
agent, _ := oleutil.CreateDispatch("Agent.Control.1")
oleutil.PutProperty(agent, "Connected", true)
result, _ := oleutil.GetProperty(agent, "Characters")
characters := result.ToIDispatch()
oleutil.CallMethod(characters, "Load", "Merlin", "c:\\windows\\msagent\\chars\\Merlin.acs")
result, _ = oleutil.CallMethod(characters, "Character", "Merlin")
character := result.ToIDispatch()
oleutil.CallMethod(character, "Show")
oleutil.CallMethod(character, "Speak", "こんにちわ世界")
syscall.Sleep(4000000000)
}
よかったら遊んでみて下さい。