Freeing C variables in Golang? - c

I'm confused about which variables need to be freed if I'm using C variables in Go.
For example, if I do this:
s := C.CString(`something`)
Is that memory now allocated until I call C.free(unsafe.Pointer(s)), or is that OK to be garbage collected by Go when the function ends?
Or is it only variables that are created from the imported C code that need to be freed, and these C variables created from the Go code will be garbage collected?

The documentation does mention:
// Go string to C string
// The C string is allocated in the C heap using malloc.
// It is the caller's responsibility to arrange for it to be
// freed, such as by calling C.free (be sure to include stdlib.h
// if C.free is needed).
func C.CString(string) *C.char
The wiki shows an example:
package cgoexample
/*
#include <stdio.h>
#include <stdlib.h>
void myprint(char* s) {
printf("%s", s);
}
*/
import "C"
import "unsafe"
func Example() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
The article "C? Go? Cgo!" shows that you don't need to free C numeric types:
func Random() int {
var r C.long = C.random()
return int(r)
}
But you would for string:
import "C"
import "unsafe"
func Print(s string) {
cs := C.CString(s)
C.fputs(cs, (*C.FILE)(C.stdout))
C.free(unsafe.Pointer(cs))
}

Related

How to get values from a C Struct in python?

So I created golang code to pass a value to a C struct and then return it into a pointer so that I can get the value in py. But am I able to get the values from the C struct in py? If so, how can I? My main goal is to pass multiple values from go to the C struct then get those values in py. Also what is the right way to do this without any memory leaks?
Heres my go code:
package main
/*
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
typedef struct Resp {
char *response;
char *responsetwo;
} Resp;
void fill(Resp *r) {
printf("Original value: %s\n", r->response);
}
*/
import "C"
import (
"unsafe"
)
func body_string(body string, body_two string) unsafe.Pointer {
sb := C.CString(body)
sb_two := C.CString(body_two)
// adding it to the C struct
return &C.Resp{
response: sb,
responsetwo: sb_two,
}
}
I am not sure if this is the most efficient way, but is this okay for large text values? Thank you.

C call Go exported function

I want to return an array to C caller, just like below, how to do it?
//export EtcdGetAllNodes
func EtcdGetAllNodes()[]uint32 {
a := []uint32{1,2,3}
return a
}
This function EtcdGetAllNodes will try to get value with a prefix for the specific key from etcd, it will return multiple values. How to return these values to C caller?
Command cgo
Passing pointers
A Go function called by C code may not return a Go pointer (which
implies that it may not return a string, slice, channel, and so
forth). A Go function called by C code may take C pointers as
arguments, and it may store non-pointer or C pointer data through
those pointers, but it may not store a Go pointer in memory pointed to
by a C pointer. A Go function called by C code may take a Go pointer
as an argument, but it must preserve the property that the Go memory
to which it points does not contain any Go pointers.
I want to return an array to C caller.
//export EtcdGetAllNodes
func EtcdGetAllNodes() []uint32 {
a := []uint32{1, 2, 3}
return a
}
A Go function called by C code may not return a Go pointer (which implies that it may not return a slice).
There are many possible solutions: Command cgo.
For example, here is one simple solution:
Output:
$ go build -buildmode=c-archive -o cmem.a cmem.go
$ gcc -pthread -o cmem cmem.c cmem.a
$ ./cmem
-- EtcdGetAllNodes --
nodes: 3
node 0: 1
node 1: 2
node 2: 3
$ echo $?
0
$
cmem.go:
package main
/*
#include <stdint.h>
#include <stdlib.h>
*/
import "C"
import "unsafe"
// toC: Go slice to C array
// c[0] is the number of elements,
// c[1] through c[c[0]] are the elements.
// When no longer in use, free the C array.
func toC(a []uint32) *C.uint32_t {
// C array
ca := (*C.uint32_t)(C.calloc(C.size_t(1+len(a)), C.sizeof_uint32_t))
// Go slice of C array
ga := (*[1 << 30]uint32)(unsafe.Pointer(ca))[: 1+len(a) : 1+len(a)]
// number of elements
ga[0] = uint32(len(a))
// elements
for i, e := range a {
ga[1+i] = e
}
return ca
}
//export EtcdGetAllNodes
// EtcdGetAllNodes: return all nodes as a C array.
// nodes[0] is the number of node elements.
// nodes[1] through nodes[nodes[0]] are the node elements.
// When no longer in use, free the nodes array.
func EtcdGetAllNodes() *C.uint32_t {
// TODO: code to get all etcd nodes
a := []uint32{1, 2, 3}
// nodes as a C array
return toC(a)
}
func main() {}
cmem.c:
#include "cmem.h"
#include <stdint.h>
#include <stdio.h>
int main() {
printf("-- EtcdGetAllNodes --\n");
// nodes[0] is the number of node elements.
// nodes[1] through nodes[nodes[0]] are the node elements.
// When no longer in use, free the nodes array.
uint32_t *nodes = EtcdGetAllNodes();
if (!nodes) {
return 1;
}
printf("nodes: %d\n", *nodes);
for (uint32_t i = 1; i <= *nodes; i++) {
printf("node %d: %d\n", i-1,*(nodes+i));
}
free(nodes);
return 0;
}

Calling a C function with a double pointer output parameter using CGo

I am trying to figure out th right way to call this function:
size_t
fz_buffer_storage(fz_context *ctx, fz_buffer *buf, unsigned char **datap)
{
if (datap)
*datap = (buf ? buf->data : NULL);
return (buf ? buf->len : 0);
}
using CGo to get the underlying string and its length as a byte array in Go.
Is this the right way to do it?
var bufferContents *C.uchar
length := C.fz_buffer_storage(ctx, buf, &bufferContents)
bytes := C.GoBytes(unsafe.Pointer(bufferContents), C.int(length))
Since the C code overwrites *datap, I am not sure if the garbage collector will still do the right thing.
I saw an answer here suggesting something along the lines of
var tempUcharPtr *C.uchar
bufferContents := C.malloc(C.size_t(unsafe.Sizeof(tempUcharPtr)))
defer C.free(bufferContents)
length := C.fz_buffer_storage(ctx, buf, (**C.uchar)(bufferContents))
bytes := C.GoBytes(unsafe.Pointer(*(**C.uchar)(bufferContents)), C.int(length))
which also seems to work, but it's much more convoluted and I'm wondering if it's better / safer than the previous version.
Apparently, the first version is fine. Quoting the docs:
Go code may pass a Go pointer to C provided the Go memory to which it points does not contain any Go pointers.
From what I understand, since var bufferContents *C.uchar will be initialised to nil, it does not count as a "Go pointer" for the above rule. The following simplified code examples confirm this:
package main
// void F(char **p) {}
import "C"
func main() {
var p *C.char = new(C.char)
C.F(&p)
}
will trigger "panic: runtime error: cgo argument has Go pointer to Go pointer"
package main
// void F(char **p) {}
import "C"
func main() {
var p *C.char
C.F(&p)
}
works just fine, even when setting GODEBUG=cgocheck=2.
Thanks to the folks on the #cgo channel on the Gophers Slack community for helping me understand this!

CGO: How do you use pointers in Golang to access data from an array in C

I'm writing an app for the windows platform using FFmpeg and it's golang wrapper goav, but I'm having trouble understanding how to use the C pointers to gain access to the data array they point to.
I'm trying to get the data stored in the AVFrame class and use Go to write it to a file, and eventually a texture in OpenGl to make a video player with cool transitions.
I think understanding how to cast and access the C data will make coding this a lot easier.
I've stripped out all the relevant parts of the C code, the wrapper and my code, shown below:
C code - libavutil/frame.h
#include <stdint.h>
typedef struct AVFrame {
#define AV_NUM_DATA_POINTERS 8
uint8_t *data[AV_NUM_DATA_POINTERS];
}
Golang goav wrapper - I don't really know whats going on here with the unsafe.Pointers and casting but it gives me access to the underlying C code
package avutil
/*
#cgo pkg-config: libavutil
#include <libavutil/frame.h>
#include <stdlib.h>
*/
import "C"
import (
"unsafe"
)
type Frame C.struct_AVFrame
func AvFrameAlloc() *Frame {
return (*Frame)(unsafe.Pointer(C.av_frame_alloc()))
}
func Data(f *Frame) *uint8 {
return (*uint8)(unsafe.Pointer((*C.uint8_t)(unsafe.Pointer(&f.data))))
}
My Golang code
package main
import "github.com/giorgisio/goav/avutil"
func main() {
videoFrame := avutil.AvFrameAlloc()
data := avutil.Data(videoFrame)
fmt.Println(data) // here i want the values from data[0] to data[7], but how?
}
Since the library author did not construct a slice header for you to work with you will instead need to cast the return value you get to an unsafe.Pointer and then to a uintptr this will allow you to perform pointer arithmetic on it to get elements later in memory.
Here's some example code that should run as-is on the go playground.
package main
import (
"fmt"
"unsafe"
)
func main() {
nums := []uint8{1, 2, 3, 4, 5, 6, 7, 8}
val := &nums[0] // val is the equivalent of the *uint8 the Data function returns
ptr := unsafe.Pointer(val)
sixthVal := (*uint8)(unsafe.Pointer(uintptr(ptr) + 5*unsafe.Sizeof(*val)))
fmt.Println("Sixth element:", *sixthVal)
}
Of course, you will need to be very certain you know how many elements there are so that you do not access invalid memory.

What is the best way to call into Swift from C?

Calling into C from Swift is pretty simple, however I'm looking into making a bi-directional wrapper in C, so my C has to call Swift functions.
Right now, I can do this by declaring function pointers in C, and having my C functions call them after the Swift side has set them up to call code in Swift.
My C header file:
typedef void (*callback_t)(void);
void callBackIntoSwift( callback_t cb );
My C implementation file:
#include "stuff.h"
#include <stdio.h>
void callBackIntoSwift( callback_t cb )
{
printf( "Will call back into Swift\n" );
cb();
printf( "Did call back into Swift\n" );
}
After including my C header file in the bridging header, I can do the following on the Swift side:
let cb: callback_t = {
someKindOfSwiftFunction()
}
callBackIntoSwift( cb )
Or even:
callBackIntoSwift {
someKindOfSwiftFunction()
}
Is there a better way to do this, where function pointers and callbacks are not needed? I'd like to let the C-side call someKindOfSwiftFunction directly … but when I try to apply #convention (c) to function declarations I get the message that the attribute can only be applied to types, and not declarations.
Any ideas or codebases in e.g. Github I can take a look at?
According to Joe Groff:
There’s no official way yet. Aside from name mangling, Swift functions use a different calling convention from C. Unofficially, if you’re willing to deal with more than the usual amount of code breakage and compiler bugs, there’s an unofficial attribute #_cdecl that does this:
#_cdecl("mymodule_foo")
func foo(x: Int) -> Int {
return x * 2
}
which you can then call from C:
#include <stdint.h>
intptr_t mymodule_foo(intptr_t);
intptr_t invoke_foo(intptr_t x) {
return mymodule_foo(x);
}
You can do something like this:
FileSwift.swift
public class SwiftTest: NSObject {
#objc public static func testMethod() {
print("Test")
}
}
FileSwiftWrapper.h
void SwiftFunctionWrapper();
FileSwiftWrapper.m
#import "ProductModuleName-Swift.h"
void SwiftFunctionWrapper() {
[SwiftTest testMethod];
}
Passing values between C and Swift
In C
extern char *mySwiftFunction(char *valuefromc);
int checkSwiftFuncation(void )
{
char *retval = mySwiftFunction("samplevalue");
printf("value %s\n",retval);
return 0;
}
In Swift
#_silgen_name("mySwiftFunction") // vital for the function being visible from C
func mySwiftFunction(valuefromc: UnsafePointer<Int8>) -> UnsafeMutablePointer<Int8>
{
let value = String(cString: valuefromc, encoding: .utf8)
print ("mySwiftFUnction called in Swift with \(value!)")
let retmsg = "return message"
return retmsg.charpointer
}
extension String {
var charpointer: UnsafeMutablePointer<Int8> {
return UnsafeMutablePointer(mutating: (self as NSString).utf8String!)
}}

Resources