LoginSignup
4
6

More than 1 year has passed since last update.

Go言語でDLLの関数(システムコール)を呼び出す

Last updated at Posted at 2019-01-04

★★★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)
}

実行するとメッセージボックスが表示されました。

image.png

4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6