LoginSignup
6
8

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-05-12

狙い

古い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(
が非常に冗長に感じる

6
8
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
6
8