概要
Goでfelicalib.dllを使ってIDM/PMMを取得するサンプル。
ソース自体はDLLの呼び出しをしてるだけなので、どちらかと言えば覚書。
(felicalib.dllに対するパスがハードコーディングされてるので修正してください。)
必要なもの
- Golang 32bit版
- felicalib.dllが64bit対応してないので32bit版で。次のバージョンで対応するとの書き込みからはや五年…
- PaSoRi
- RC-S380でテスト
- NFC/Felicaポートソフトウェア(v5.4.3.4を利用)
- Felicalib.dll(v0.4.2を利用)
サンプルコード
nfc-sample.go
package main
import (
"log"
"syscall"
"unsafe"
)
func main() {
// ここにfelicalib.dllのパスを入力。
var tPath = "D:/tools/felicalib-0.4.2/felicalib.dll"
dll, err := syscall.LoadDLL(tPath)
if err != nil {
log.Fatal(err)
}
defer dll.Release()
// define procedures
pasori_open, err := dll.FindProc("pasori_open")
if err != nil {
log.Fatal(err)
}
pasori_close, err := dll.FindProc("pasori_close")
if err != nil {
log.Fatal(err)
}
pasori_init, err := dll.FindProc("pasori_init")
if err != nil {
log.Fatal(err)
}
felica_polling, err := dll.FindProc("felica_polling")
if err != nil {
log.Fatal(err)
}
felica_free, err := dll.FindProc("felica_free")
if err != nil {
log.Fatal(err)
}
felica_getidm, err := dll.FindProc("felica_getidm")
if err != nil {
log.Fatal(err)
}
felica_getpmm, err := dll.FindProc("felica_getpmm")
if err != nil {
log.Fatal(err)
}
// felica_read_without_encryption02, err := dll.FindProc("felica_read_without_encryption02")
// if err != nil {
// log.Fatal(err)
// }
// errorチェックは、第一返り値の結果を判定
// 第三返り値(lastErr)はいつもsuccess
// lastErr != nilでチェックすると、successのときも値が入っている。
tPasori, _, _ := pasori_open.Call(0)
println("open", tPasori)
if(tPasori == uintptr(0)) {
log.Fatal("多分、端末が接続されてない")
}
defer pasori_close.Call(tPasori)
ret, _, _ := pasori_init.Call(tPasori)
println("init", ret)
if(ret != 0) {
log.Fatal("エラー出ることあるの?")
}
// tFelicaは、C側で内部的にメモリ確保されてる。
// 従って多分開放しないと駄目
tFelica, _, _ := felica_polling.Call(tPasori, 0xFFFF, 0, 0)
println("poll", tFelica)
if(tFelica == uintptr(0)) {
log.Fatal("NFCカードの読み込み失敗。")
}
defer felica_free.Call(tFelica)
// tFelicaで確保されえいる領域の一部を取得する。
// 従って、失敗することはまずない。
tIdm := uint64(1) // make([]byte, 8) ほんとはbyte[8]で取りたいんだけど、ちょいやり方不明orz
felica_getidm.Call(tFelica, uintptr(unsafe.Pointer(&tIdm)))
println("gIdm", tIdm)
tPmm := uint64(1)
felica_getpmm.Call(tFelica, uintptr(unsafe.Pointer(&tPmm)))
println("gPmm", tPmm)
}