【Go】DLLを読み書きする

  • 2019年10月11日
  • Go

 DLL(Dynamic Link Library)はWindowsのOSに近い階層で動作するバイナリアプリです。Libraryとある様に他のプログラムに使われることが意識されています。この他のプログラムの範囲にDLL外のプログラムも含まれている点で独特です。
ダイナミックリンクライブラリ – Wikipedia
DLL とは
 DLLを読むことは多くの言語でできるようです。少なくともJavaScript、PHP、Python、Go言語で可能です。作る方はどうにも少ないようです。この記事ではGo言語でDLLを作成する方法も紹介します。
 読み込みはsyscallパッケージを用います。言語開発者がさじを投げて仕切り直そうとしている部分ですが、とりあえず今動かしてHello Worldするぐらいならできます。
 syscall – The Go Programming Language
 src/syscall/dll_windows.go – The Go Programming Language
 読み込みは次の様にできます。ただ実行するだけでちょっと面倒なのでラッピングした方が便利そうです。


package main

import (
	"fmt"
	"syscall"
)

func main() {
	// 好きなdllを指定
	dll := syscall.MustLoadDLL("Hoge.dll")
	// この関数が終わった時にDLLをメモリから解放
	defer dll.Release()
	// dll中の関数を呼び出し
	proc := dll.MustFindProc("FugaFuga")
	// 引数はuintptr型に変換
	buffer := []byte("Hello World\x00")
	arg := uintptr(unsafe.Pointer(&buffer[0]))
	// 結果を取得. 返り値は(r1, r2 uintptr, lastErr error)
	r, _, _ := proc.Call(arg)
	// 結果を表示
	fmt.Println(r)
}

 書き込みは色々と方法があるようです。一つのやりかたはC言語になりきることです。C言語のコンパイラを利用してGo言語をDLLを作ることができます。


package main

import "C"

// ↓のコメントはDLLのためのデコレータ

//export GetRouteFilename
func GetRouteFilename() int {
	// DLL内で実行される関数の中身
	msg := []byte("Hello World")
	println(msg)
	return 0
}

func main() {
	// main()がないとバグる
}

 これを次のコマンドでコンパイルするとDLLが作られます。

go build -buildmode=c-shared  -o godll.dll godll.go
>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG