Help us understand the problem. What is going on with this article?

Golang で過去の遺物的(cp932)DLLを利用する

More than 3 years have passed since last update.

狙い

古いDLLは文字コードにCP932を使ってるものがあるが
web上に見受けられる文献にはこれらの遺物を利用する方法が見つからないのでここに記述する。

コード

call_msgbox.go
package main

import (
    "syscall"
    "unsafe"

    "golang.org/x/text/encoding/japanese"
    "golang.org/x/text/transform"
)

func cp932(str string) string {
    r, _, err := transform.String(japanese.ShiftJIS.NewEncoder(), str)
    if err != nil {
        panic(err)
    }
    return r
}
func cp932ptr(str string) *byte {
    return syscall.StringBytePtr(cp932(str))
}

func main() {
    user32 := syscall.MustLoadDLL("user32.dll")
    defer user32.Release()
    MessageBoxA := user32.MustFindProc("MessageBoxA")
    MessageBoxW := user32.MustFindProc("MessageBoxW")

    //wide char = utf16le
    MessageBoxW.Call(0,
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("日本語の表示"))),
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("UTF16LEの場合"))),
        0)

    // cp932
    MessageBoxA.Call(0,
        uintptr(unsafe.Pointer(cp932ptr("日本語の表示"))),
        uintptr(unsafe.Pointer(cp932ptr("CP932の場合"))),
        0)

    // UTF8もANSI互換なので英数字のみならば
    MessageBoxA.Call(0,
        uintptr(unsafe.Pointer(syscall.StringBytePtr("ascii only"))),
        uintptr(unsafe.Pointer(syscall.StringBytePtr("utf8 is ANSI"))),
        0)
}

反省点

あくまでCP932(いわゆるSJIS)用である。
ユーザーの入力をOSのANSI関数に渡す場合にはWideCharToMultiByteを利用して
UTF16へ変換 -> WideCharToMultiByte -> CP_ACP へ変換してやるべき

一言

uintptr(unsafe.Pointer(
が非常に冗長に感じる

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away