Pass struct and array of structs to C function from Go
I know this is a fairly old topic but I stumbled across it. Here's a modified (correct) version with some additional manipulation from C land on the Go structs.
package main
/*
#include <stdio.h>
typedef struct {
int a;
int b;
} Foo;
void pass_struct(Foo *in) { printf("%d : %d\n", in->a, in->b); }
void pass_array(Foo **in, int len) {
for(int i = 0; i < len; i++) {
pass_struct(in[i]);
in[i]->a += 1;
in[i]->b += 1;
}
}
*/
import "C"
import (
"fmt"
"unsafe"
)
type Foo struct{ a, b int32 }
func main() {
foo := Foo{10, 20}
foos := []*Foo{&Foo{1, 2}, &Foo{3, 4}}
fmt.Println("from C land")
C.pass_struct((*C.Foo)(unsafe.Pointer(&foo)))
C.pass_array((**C.Foo)(unsafe.Pointer(&foos[0])), C.int(len(foos)))
fmt.Println("a & b should have incremented with 1")
fmt.Println("from Go land")
for _, foo := range foos {
fmt.Printf("%d : %d\n", foo.a, foo.b)
}
}
Output:
from C land
10 : 20
1 : 2
3 : 4
a & b should have incremented with 1
from Go land
2 : 3
4 : 5
The problem is that Foo
and _Ctype_Foo
are different structures.
I would guess you are running on 64 bit. Note that int
is 64 bit in go, but is quite likely to be 32 bit in C.
If I change the definition of Foo
to this then it works on my machine (64 bit linux)
type Foo struct {
A int32
B int32
}
However I would say that is a recipe for trouble - make your Go and C code use the same structure with
type Foo _Ctype_Foo