2025年1月31日金曜日

Go言語入門(2)

 

興味本位でGo言語に触れてみようと思う。Linuxのshared libraryを呼び出してみる。


では、まずshared libraryを作るんだけど、以前作ったkeeloqでやってみる。こちら(https://sunday-engineer.jimdofree.com/2023/09/08/keeloq%E3%82%92%E9%A1%8C%E6%9D%90%E3%81%ABlinux%E5%85%B1%E6%9C%89%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA/)
まぁそれは出来るっていう体で
mkdir callshared
cd callshared
mkdir keeloq
cd keeloq
で、こちらにkeeloqのshared libraryを作って、で、念のため、Cからcallしてみる。

keeloq_call.c
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <dlfcn.h>
  4. typedef uint32_t (*keeloq_enc_type)(uint32_t pr,uint64_t kr);
  5. typedef uint32_t (*keeloq_dec_type)(uint32_t cr,uint64_t kr);
  6. void* dll;
  7. keeloq_enc_type keeloq_enc;
  8. keeloq_dec_type keeloq_dec;
  9.  
  10. int main(int argc,char** argv){
  11.     uint32_t pr=0xf741e2db;
  12.     uint64_t kr=0x5cec6701b79fd949;
  13.     uint32_t cr;
  14.     dll=dlopen("./libkeeloq.so",RTLD_LAZY);
  15.     keeloq_enc=(keeloq_enc_type)dlsym(dll,"keeloq_enc");
  16.     keeloq_dec=(keeloq_dec_type)dlsym(dll,"keeloq_dec");
  17.  
  18.     cr=keeloq_enc(pr,kr);
  19.     printf("%08X\n",cr);
  20.     pr=keeloq_dec(cr,kr);
  21.     printf("%08X\n",pr);
  22.     return 0;
  23. }
で、
gcc keeloq.c
./a.out
まぁ、うまくいきます。
では、
cd ..
で、Goのコードを書く。
ちなみに、treeするとこういう状態。(pythonのテストコードとかもあったりする;)

  • callshared
  • ├── callshared.go
  • └── keeloq
  •     ├── Makefile
  •     ├── a.out
  •     ├── keeloq.c
  •     ├── keeloq.o
  •     ├── keeloq_call.c
  •     ├── keeloq_call.py
  •     ├── libkeeloq.map
  •     └── libkeeloq.so

callshared.go
  1. package main
  2.  
  3. /*
  4. #cgo LDFLAGS: -ldl
  5. #include <dlfcn.h>
  6. #include <stdint.h>
  7. uint32_t call_func(void* p,uint32_t a,uint64_t b){
  8.     uint32_t (*func)(uint32_t a, uint64_t b) = p;
  9.     return func(a, b);
  10. }
  11. */
  12. import "C"
  13. import "fmt"
  14. func main() {
  15.     var pr C.uint32_t
  16.     var cr C.uint32_t
  17.     var kr C.uint64_t
  18.     pr = 0xf741e2db
  19.     kr = 0x5cec6701b79fd949
  20.     dll := C.dlopen(C.CString("./keeloq/libkeeloq.so"), C.RTLD_LAZY)
  21.     if dll == nil {
  22.         panic("Failed to open shared object.")
  23.     }
  24.     defer C.dlclose(dll) //<--これ意味わからんのよね
  25.     keeloq_enc := C.dlsym(dll, C.CString("keeloq_enc"))
  26.     if keeloq_enc == nil {
  27.         panic("Could not found function pointer.")
  28.     }
  29.     keeloq_dec := C.dlsym(dll, C.CString("keeloq_dec"))
  30.     if keeloq_dec == nil {
  31.         panic("Could not found function pointer.")
  32.     }
  33.     cr = C.call_func(keeloq_enc, pr, kr)
  34.     fmt.Printf("%08X\n", cr)
  35.     pr = C.call_func(keeloq_dec, cr, kr)
  36.     fmt.Printf("%08X\n", pr)
  37. }
これってcgoってのを利用しているらしい。コメントの中の記述に従って動作している。powershellがC#のコードを実行できるのと似ている。なんか変な感じだけどね。コメントの中のC記述とimport "C"は行をあけずにぴったりひっつけてないとダメらしい。コメントの中では関数ポインタとその関数の引数を引数として受け取って、関数ポインタで指示された関数を実行して結果を戻している。今回は2つの関数をcallしているけど、型が同じなので記述を共用している。
で、
go run callshared.go
って感じで、Cでやった結果とおんなじになりました。
いきなりshared libraryをcallするってGoやる気あるんか?って?、、、うむぅ

0 件のコメント:

コメントを投稿