How do I add a golang string to a c struct that I made in cgo. Heres the code:
package main
/*
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
typedef struct Point {
int x, y;
} Point;
typedef struct Resp {
char response;
} Resp;
*/
import "C"
import (
"fmt"
"io/ioutil"
"unsafe"
)
type CPoint struct {
Point C.Point
Resp C.Resp
}
func main() {
var r string = "Hello World"
resp := unsafe.Pointer(C.char(r))
point := CPoint{
Point: C.Point{x: 1, y: 2},
Resp: C.Resp{response: resp},
}
fmt.Println(point)
}
But whenever I run this I get this error
cannot convert r (type string) to type _Ctype_char
How do I fix this? How can I conver r to type _Ctype_char?
Also how would you get the value in the c struct "Resp"?
package main
/*
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
typedef struct Point {
int x, y;
} Point;
typedef struct Resp {
char response; // <-- How can I get this value in my go code?
} Resp;
*/
CodePudding user response:
Your code needs 2 fixes:
- C
char
only represents a single character/byte - not a string. C strings arechar*
. - You should use
C.CString
to allocate a C string from Go, andC.free
to release it. See: https://pkg.go.dev/cmd/cgo#hdr-Go_references_to_C.
Here is your example with these fixes:
package main
// FIX: "char response" replaced with "char *response" below.
/*
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
typedef struct Point {
int x, y;
} Point;
typedef struct Resp {
char *response;
} Resp;
*/
import "C"
import (
"fmt"
"unsafe"
)
type CPoint struct {
Point C.Point
Resp C.Resp
}
func main() {
// FIX: Use CString to allocate a *C.char string.
resp := C.CString("Hello World")
point := CPoint{
Point: C.Point{x: 1, y: 2},
Resp: C.Resp{response: resp},
}
fmt.Println(point)
// Example of converting a C *char to a Go string:
goResp := C.GoString(point.Resp)
fmt.Println(goResp)
// FIX: Release manually allocated string with free(3) when no longer needed.
C.free(unsafe.Pointer(resp))
}