★★★2021/11/23追記★★★
mksyscall_windows.go
というツールを使っていますが、あまりちゃんと認識していませんでした。
(今も深くは理解していませんが)このツール自体名前からして、Windowsのシステムコールを作るものですね。
「任意のDLLの関数を呼び出す方法」としては不適切だったため、タイトルを変更しました。
こちらを参考にさせていただきました:Big Sky :: golang で型付きで DLL を呼び出す方法
―――――――――――
まず、以下を定義したsyscall_windows.go
というファイルを作成しました。
-
go generate
向けの、ツールmksyscall_windows.go
で中間コードzsyscall_windows.go
を生成する定義 -
mksyscall_windows.go
向けの、DLL関数をラップするGo言語関数の定義
syscall_windows.go
package main
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go
//sys messageBox(hWnd syscall.Handle, lpText string, lpCaption string, uType uint32) (dwRet uint32, err error) = User32.MessageBoxW
go generate
を実行すると、以下のようなコードが生成されます。
zsyscall_windows.go(抜粋)
func messageBox(hWnd syscall.Handle, lpText string, lpCaption string, uType uint32) (dwRet uint32, err error) {
var _p0 *uint16
_p0, err = syscall.UTF16PtrFromString(lpText)
if err != nil {
return
}
var _p1 *uint16
_p1, err = syscall.UTF16PtrFromString(lpCaption)
if err != nil {
return
}
return _messageBox(hWnd, _p0, _p1, uType)
}
func _messageBox(hWnd syscall.Handle, lpText *uint16, lpCaption *uint16, uType uint32) (dwRet uint32, err error) {
r0, _, e1 := syscall.Syscall6(procMessageBoxW.Addr(), 4, uintptr(hWnd), uintptr(unsafe.Pointer(lpText)), uintptr(unsafe.Pointer(lpCaption)), uintptr(uType), 0, 0)
dwRet = uint32(r0)
if dwRet == 0 {
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
}
return
}
―★疑問★――――――
dwRet
(異常時は0
)がうまいことエラーハンドリングされているように見えます。
正常時に0
となる関数はどうするのでしょう。
★★★2021/11/23追記★★★
Windowsのシステムコールを扱う関数なので、DWRODが返る時点で異常時が0、という扱いなのかも。
―――――――――――
あとは生成されたmessageBox()
を呼び出せばOKです。
main.go
package main
func main() {
messageBox(0, "message", "title", 0)
}
実行するとメッセージボックスが表示されました。