Skip to content

Commit

Permalink
Add 26.C_malloc_struct
Browse files Browse the repository at this point in the history
  • Loading branch information
devlights committed Nov 11, 2024
1 parent 011799e commit 6789a77
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
17 changes: 17 additions & 0 deletions 26.C_malloc_struct/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# これは何?

cgoにてGo側で ```C.malloc()``` を利用して、構造体のメモリを動的確保するサンプルです。

```malloc()``` には、確保するサイズを指定する必要がありますが、通常C言語側では

```c
sizeof(struct A)
```

としますが、cgo側では以下のように構造体のサイズを取得することが出来ます。

```go
var sz = C.sizeof_struct_(構造体)
```

typedefしていない構造体を扱う場合の宣言方法は [25.C_struct_not_typedef](../25.C_struct_not_typedef/) を参照ください。
8 changes: 8 additions & 0 deletions 26.C_malloc_struct/Taskfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# https://taskfile.dev

version: '3'

tasks:
default:
cmds:
- go run .
35 changes: 35 additions & 0 deletions 26.C_malloc_struct/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package main

/*
#include <stdio.h>
#include <stdlib.h>
struct A {
int value;
};
void A_setvalue(struct A *a, int value) {
a->value = value;
}
*/
import "C"
import (
"fmt"
)

func main() {
var (
stSize = C.sizeof_struct_A // 構造体のサイズを取得し (C.sizeof_struct_(構造体名)で取得出来る)
cSize = C.size_t(stSize) // size_tに変換して
ptr = C.malloc(cSize) // malloc(*1)でメモリ確保する。この段階では (void *) なので
ptrA = (*C.struct_A)(ptr) // 適切なポインタ型にキャスト
)
defer C.free(ptr) // メモリ動的確保しているので忘れずにfreeすること
// (*1) ちなみに C.malloc() は、cgo側でカスタムな実装となっておりNULLが返ってくることは絶対にない。失敗時はpanicする。

C.A_setvalue(ptrA, 999)
fmt.Printf("value=%d\n", ptrA.value)

ptrA.value = C.int(111)
fmt.Printf("value=%d\n", ptrA.value)
}

0 comments on commit 6789a77

Please sign in to comment.