I've been experimenting with cgo these days to avoid writing C code. I have some shared libraries from C which I want to use in the go programs. So I was trying the passing pointer to C function from Go and got a panic! So let the code do the talking below is the code I used.
#ifndef __POINTER_H__
#define __POINTER_H__
typedef struct {
int a;
int b;
float c;
} SampleStruct;
void GetSampleStruct(SampleStruct*);
#endif /* __POINTER_H_ */
#include <string.h>
#include "pointer.h"
void GetSampleStruct(SampleStruct *t){
SampleStruct temp = {1,2,3.0};
memcpy(t, &temp, sizeof(SampleStruct));
return;
}
package main
/*
#include "pointer.h"
*/
import "C"
import "fmt"
type SStruct struct {
s *C.SampleStruct
}
func main(){
var ss SStruct
fmt.Printf("Trying to read a structure by passing pointer\n")
C.GetSampleStruct(ss.s);
fmt.Printf("SampleStruct read!:\n")
fmt.Printf("a: %d b: %d c: %f",ss.s.a, ss.s.b, ss.s.c)
}
So I'm just passing a pointer to C function GetSampleStruct which will use memcpy to copy values into this passed pointer location. When I compile and try to run this program I get a panic from go runtime. I'm pasting this below
Trying to read a structure by passing pointer
SIGSEGV: segmentation violation
PC=0x8048cdf
signal arrived during cgo execution
runtime.cgocall(0x8048ca0, 0xb7448f48)
/usr/local/go/src/pkg/runtime/cgocall.c:149 +0x10c fp=0xb7448f3c
main._Cfunc_GetSampleStruct(0x0)
_/home/vasudev/go/src/testpointer/_obj/_cgo_defun.c:50 +0x31 fp=0xb7448f48
main.main()
/home/vasudev/go/src/testpointer/pointer.go:18 +0x46 fp=0xb7448f98
runtime.main()
/usr/local/go/src/pkg/runtime/proc.c:220 +0xff fp=0xb7448fcc
runtime.goexit()
/usr/local/go/src/pkg/runtime/proc.c:1394 fp=0xb7448fd0
goroutine 3 [syscall]:
runtime.goexit()
/usr/local/go/src/pkg/runtime/proc.c:1394
eax 0x0
ebx 0x8169584
ecx 0xb75576d0
edx 0xb7448f0c
edi 0x18401140
esi 0x81703e0
ebp 0x8171a40
esp 0xbf9b83dc
eip 0x8048cdf
eflags 0x10282
cs 0x73
fs 0x0
gs 0x33
So it happens at line where I call C.GetSampleStruct function, so I guess this is because the ss.s is possibly unallocated but I'm not sure. I don't know if there is a malloc function available in Go to allocate pointers from C or if its safe to do so. I'm totally lost and looking forward for some Golang experts to give me some hints.
You got a SEGV because you passed nil, here
main._Cfunc_GetSampleStruct(0x0)
_/home/vasudev/go/src/testpointer/_obj/_cgo_defun.c:50 +0x31 fp=0xb7448f48
because the zero value of SStruct.s is nil, it's a pointer
Try something like
var s C.SimpleStruct
C.GetSampleStruct(&s)