é¢é£è¨äº
Goメモ-502 (cgoメモ-01)(cgoヘッダ) - いろいろ備忘録日記
Goメモ-506 (cgoメモ-02)(cgoヘッダ) - いろいろ備忘録日記
Goメモ-507 (cgoメモ-03)(C.int) - いろいろ備忘録日記
Goメモ-508 (cgoメモ-04)(C言語の構造体) - いろいろ備忘録日記
Goメモ-509 (cgoメモ-05)(C.CString)(Cの文字列) - いろいろ備忘録日記
Goメモ-510 (cgoメモ-06)(C.GoString)(Cの文字列をGoの文字列へ) - いろいろ備忘録日記
Goメモ-511 (cgoメモ-07)(C.CBytes)([]byteをCのバイト列に) - いろいろ備忘録日記
Goメモ-512 (cgoメモ-08)(C.GoBytes)(Cのバイト列をGoの[]byteへ) - いろいろ備忘録日記
Goメモ-514 (cgoメモ-09)(C.GoStringN)(C.GoStringのサイズ指定版) - いろいろ備忘録日記
GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ
æ¦è¦
以ä¸ãèªåç¨ã®ã¡ã¢ã§ãã
ä»åããè¤æ°åã«æ¸¡ã£ã¦ cgo ã«ã¤ãã¦ã¡ã¢ãã¦ãããã¨æãã¾ãã
cgo ã¯ãæåéãGoããCã«ã¢ã¯ã»ã¹ãããã¨ãåºæ¥ãããã«ãªããã®ãªã®ã§ãããã¨ã¦ã便å©ãªåé¢ãçµæ§ã¯ã»ãå¼·ãã®ã§ã¡ã¢ã§ãæ®ãã¦ãããªãã¨ããé ããæ¶ãã¦ãã¾ãããã ãªã£ã¦æãã¾ããã
Cgo is not Go
ã¨ããæ ¼è¨ããã£ããããã®ã§ãGoçéã§æ¨æºã§æ¨å¥¨ããã¦ããªãæè¡ããããã¾ãããããå®åã§ã¯Cè¨èªã§ä½æãããã©ã¤ãã©ãªãªã©ã¯å±±ã®ããã«ããã¾ãããã§ãããã¸ã§ã¯ãã®æ¹éã§Goã§ä½ãç´ããã¨ãåºæ¥ãªãå ´åãå¤ã ããã¾ãããã®ãããªå ´åã«é常ã«ä¾¿å©ã§ãã
ããããã®ãµã³ãã«ã¯ä»¥ä¸ã®ãªãã¸ããªã«ã¢ãããã¦ããã¾ãã®ã§ãè¯ããã°ãåèãã ããã
ä»å㯠cgo 㧠[]byte
ã (void *)
ã¸å¤æããããæ¹ã«ã¤ãã¦ã
Goã® []byte
ã Cè¨èªå´ã®ãã¤ãåã«ããã«ã¯ä»¥åæ¸ãã C.CBytes()
ã使ãã°å¯è½ãªã®ã§ããããããå©ç¨ããã«ãã£ã¦ã¿ã¾ãããã£ã¦è©±ã§ãã
Cè¨èªå´ã®APIã¯å¾ã
ã«ã㦠(void *)
ã沢山åºã¦ãããã®ã§ãããªã®ã§ãGoãã (void *)
ãåãæ¹æ³ãè¦ãã¦ããã¨APIã©ããã¼ãªã©ã®ä½æãããããããªãã¾ãã
C.CBytes()
ãç¨ããã«ã[]byte
ã(void *)
ã«å¤æããã«ã¯ä»¥ä¸ã®æé ãè¸ã¿ã¾ãã
- ã¹ã©ã¤ã¹ã®å é è¦ç´ ã®ãã¤ã³ã¿ãåå¾
unsafe.Pointer
ãåå¾
cgoã§ã¯ãunsafe.Pointer()
ãCã® (void *)
ã«å½ããã¾ãã
Cè¨èªã§ã¯å¼ã®ä¸ã§ä½¿ãé åã¯ããå é è¦ç´ ã®ãã¤ã³ã¿ãã«èªã¿æ¿ãã¦ãããã¾ãã®ã§ãCè¨èªä¸ã§ã¯é ååããã®ã¾ã¾æå®ããã°è¯ãã®ã§ãããGoã¯Cè¨èªã§ã¯ç¡ãã®ã§å½ç¶ãããåºæ¥ã¾ããã
ãªã®ã§ãæ示çã«å é è¦ç´ ã®ãã¤ã³ã¿ãæå®ããå¿ è¦ãããã¾ãã
ãµã³ãã«
main.go
package main /* #include <stdio.h> #include <stdlib.h> #include <string.h> const int BUF_SIZE = 11; void setBuf(void *buf) { strncpy((char *)buf, "helloworld", BUF_SIZE-1); } */ import "C" import ( "encoding/hex" "fmt" "unsafe" ) func main() { var ( buf = make([]byte, int(C.BUF_SIZE)) bufPtr = unsafe.Pointer(&buf[0]) //æ示çã«å é è¦ç´ ã®ãã¤ã³ã¿ã渡ã printBuf = func() { fmt.Println(string(buf)) fmt.Println(hex.Dump(buf)) } ) printBuf() { // Cå´ã®å®£è¨ã§ã¯ (void *) ãå¼æ°ã«è¦æ±ãã¦ãããããunsafe.Pointer ã渡ã. // unsafe.Pointer ã¯ã (void *) ã表ã. C.setBuf(bufPtr) } printBuf() }
Taskfile.yml
# https://taskfile.dev version: '3' tasks: default: cmds: - go run main.go
å®è¡
$ task task: [default] go run main.go 00000000 00 00 00 00 00 00 00 00 00 00 00 |...........| helloworld 00000000 68 65 6c 6c 6f 77 6f 72 6c 64 00 |helloworld.|
ã¡ãã㨠(void *)
ã¨ãã¦Cå´ã«æ¸¡ã£ã¦å¤ãè¨å®åºæ¥ã¦ãã¾ããã
åèæ å ±
- C? Go? Cgo!
- Go Wiki: cgo
- cmd/cgo
- runtime/cgo
- cgoã使ã£ãCã¨Goã®ãªã³ã¯ã®è£å´ (1)
- cgoã使ã£ãCã¨Goã®ãªã³ã¯ã®è£å´ (2)
- ebitengine/purego
- JupiterRider/ffi
Goã®ããããæ¸ç±
éå»ã®è¨äºã«ã¤ãã¦ã¯ã以ä¸ã®ãã¼ã¸ãããåç §ä¸ããã
ãµã³ãã«ã³ã¼ãã¯ã以ä¸ã®å ´æã§å ¬éãã¦ãã¾ãã