4

Here is my code:

helloworld.go:

package main

import "C"
import "unsafe"

//export HelloWorld
func HelloWorld() *C.char {
    cs := C.CString("Hello World!")
    C.free(unsafe.Pointer(cs))
    return cs
}

func main() {}

One of the errors I got:

src/helloworld.go:9:2: could not determine kind of name for C.free

Based on this article: https://blog.golang.org/c-go-cgo

I also found out that I need to add #include <stdlib.h> at top of my C file.

helloworld.h:

#include <stdlib.h>
/* Created by "go tool cgo" - DO NOT EDIT. */

/* package command-line-arguments */

/* Start of preamble from import "C" comments.  */




/* End of preamble from import "C" comments.  */


/* Start of boilerplate cgo prologue.  */
#line 1 "cgo-gcc-export-header-prolog"

#ifndef GO_CGO_PROLOGUE_H
#define GO_CGO_PROLOGUE_H

typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt64 GoInt;
typedef GoUint64 GoUint;
typedef __SIZE_TYPE__ GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128;

/*
  static assertion to make sure the file is being used on architecture
  at least with matching size of GoInt.
*/
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];

typedef struct { const char *p; GoInt n; } GoString;
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;

#endif

/* End of boilerplate cgo prologue.  */

#ifdef __cplusplus
extern "C" {
#endif


extern char* HelloWorld();

#ifdef __cplusplus
}
#endif

I tried it to no success.

I need to free the memory.

How do I do this? Because in there example it prints out the string. I want to return it. Without C.free. I am able to do it. I am just worried of causing a memory leak or some other issue.

kostix
  • 51,517
  • 14
  • 93
  • 176
jnbdz
  • 4,863
  • 9
  • 51
  • 93

1 Answers1

1

Command cgo

// 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

If the import of "C" is immediately preceded by a comment, that comment, called the preamble, is used as a header when compiling the C parts of the package.

For example,

package main

/*
#include <stdlib.h>
*/
import "C"

import "unsafe"

//export HelloWorld
func HelloWorld() *C.char {
    cs := C.CString("Hello World!")
    C.free(unsafe.Pointer(cs))
    return cs
}

func main() {}
peterSO
  • 158,998
  • 31
  • 281
  • 276
  • But now I am getting random strings. https://stackoverflow.com/questions/47194827/getting-unreadable-string-from-my-node-js-extension-made-with-golang By the way thanks for your help. – jnbdz Nov 09 '17 at 06:14
  • You shouldn't bee freeing the string just before you return it. If you do you'll end up with garbage. – rhody Jul 02 '20 at 22:20
  • 2 things I have observed in the above program. one is as @rhody mentioned you shouldn't return after the free call what you can do is use defer to make sure at the end you free the memory or else you will get into heap-use-after-free issues. the other thing I observed is you are not calling the HelloWorld in your main is this intentional? – Rakesh babu Mar 15 '23 at 16:23