FAQ
When calling a Go function from C, I need to construct a GoSlice or
GoString. _cgo_export.h (on tip) defines these, as well GoInterface, as:

typedef struct { char *p; int n; } GoString;
typedef struct { void *data; int len; int cap; } GoSlice;
typedef struct { void *t; void *v; } GoInterface;

I've been able to successfully construct a GoSlice pass it into the Go
function without problems.

Who is responsible for clearing "char *p" or "void *data"? If I am
responsible, when? Where - from C free(), or from Go C.free()? After the
function call? Does Go make a copy of the memory?

If GoString and GoSlice is allocated to the heap instead of the C function
stack, do I need to clear this as well? What if I have a []string that
needs to be constructed?

Lastly, how do I construct a []interface{}? The []interface{} needs to
contain string, int, uint, bool, and C.object. Would I be better off using
unsafe.Pointer with uintptr to transverse the "array" of items (using a
union struct, or something)?

Luke

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Gustavo Niemeyer at Sep 4, 2013 at 6:05 pm

    On Wed, Sep 4, 2013 at 2:54 PM, Luke Scott wrote:
    Who is responsible for clearing "char *p" or "void *data"? If I am
    responsible, when? Where - from C free(), or from Go C.free()? After the
    function call? Does Go make a copy of the memory?
    It depends on who allocated the memory.

    If Go allocated the memory, it is in an area managed by the garbage
    collector, and thus it will be deallocated automatically at some point
    after the last reference in Go land is dead. That means you cannot
    trust the string to be alive in C land, unless you're sure there's a
    reference in Go land to the same string.

    If C allocated the memory, it must be explicitly freed. That said, Go
    has no idea about whether the memory is there or not.. it will simply
    trust it to be there for as long as the string is alive, because
    that's the normal behavior with strings it allocates internally. If
    you explicitly free the memory backing the string while there is still
    a references to in Go land, the program will crash or misbehave
    arbitrarily when the string is touched again (and people will be very
    angry :-).

    Note that this is very implementation dependent. Although these
    details are unlikely to change imminently, they can change without
    much notice.
    If GoString and GoSlice is allocated to the heap instead of the C function
    stack, do I need to clear this as well? What if I have a []string that needs
    to be constructed?
    The details are similar to the above.
    Lastly, how do I construct a []interface{}? The []interface{} needs to
    contain string, int, uint, bool, and C.object. Would I be better off using
    unsafe.Pointer with uintptr to transverse the "array" of items (using a
    union struct, or something)?
    I would do that from Go instead of doing it from C.


    gustavo @ http://niemeyer.net

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Luke Scott at Sep 4, 2013 at 6:21 pm

    On Wednesday, September 4, 2013 11:05:18 AM UTC-7, Gustavo Niemeyer wrote:
    On Wed, Sep 4, 2013 at 2:54 PM, Luke Scott wrote:
    Who is responsible for clearing "char *p" or "void *data"? If I am
    responsible, when? Where - from C free(), or from Go C.free()? After the
    function call? Does Go make a copy of the memory?
    It depends on who allocated the memory.

    If Go allocated the memory, it is in an area managed by the garbage
    collector, and thus it will be deallocated automatically at some point
    after the last reference in Go land is dead. That means you cannot
    trust the string to be alive in C land, unless you're sure there's a
    reference in Go land to the same string.

    If C allocated the memory, it must be explicitly freed. That said, Go
    has no idea about whether the memory is there or not.. it will simply
    trust it to be there for as long as the string is alive, because
    that's the normal behavior with strings it allocates internally. If
    you explicitly free the memory backing the string while there is still
    a references to in Go land, the program will crash or misbehave
    arbitrarily when the string is touched again (and people will be very
    angry :-).
    I'm calling a Go function from C. In other words the Go function has
    //export above it and C is calling it. The parameters of that Go function
    is exported as a GoSlice and/or GoString type. I need to satisfy these
    arguments.

    Note that this is very implementation dependent. Although these
    details are unlikely to change imminently, they can change without
    much notice.
    Not too much of a concern as there isn't a lot of code for me to change. I
    just need to know how to handle it today.

    If GoString and GoSlice is allocated to the heap instead of the C function
    stack, do I need to clear this as well? What if I have a []string that needs
    to be constructed?
    The details are similar to the above.
    Lastly, how do I construct a []interface{}? The []interface{} needs to
    contain string, int, uint, bool, and C.object. Would I be better off using
    unsafe.Pointer with uintptr to transverse the "array" of items (using a
    union struct, or something)?
    I would do that from Go instead of doing it from C.
    I'm calling a Go function from C. I need to get a dynamic list of arbitrary
    types to Go from C.

    So if I create a GoSlice backed by a void*, if I free() that void* then Go
    no longer has access to it. Go will also not clear that memory. If I am
    passing it by value, will Go make a copy of it if I pass it into another Go
    function? I'm assuming that I probably should not take a pointer from these
    C created Go values.

    My other option is to pass an array pointer of a C struct that contains a
    type and do some pointer arithmetic by converting unsafe.Pointer to uintptr.

    What is the best approach for what I'm trying to do?

    Luke

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Gustavo Niemeyer at Sep 4, 2013 at 6:30 pm

    On Wed, Sep 4, 2013 at 3:21 PM, Luke Scott wrote:
    I'm calling a Go function from C. In other words the Go function has
    //export above it and C is calling it. The parameters of that Go function is
    exported as a GoSlice and/or GoString type. I need to satisfy these
    arguments.
    What I generally do is to declare the Go function in a more C-friendly way.

    For example:

         //export doSomething
         func doSomething(cstr *C.char, clen C.int) {
             gostr := C.GoStringN(cstr, clen)
         }

    This way the Go string is allocated and managed by Go itself.
    I'm calling a Go function from C. I need to get a dynamic list of arbitrary
    types to Go from C.

    So if I create a GoSlice backed by a void*, if I free() that void* then Go
    no longer has access to it. Go will also not clear that memory. If I am
    passing it by value, will Go make a copy of it if I pass it into another Go
    function? I'm assuming that I probably should not take a pointer from these
    C created Go values.
    Same idea. The whole process is much easier (and safer) if you hand
    over the data for Go to do the work, otherwise you'll be fighting the
    garbage collector and doing reference counting yourself.


    gustavo @ http://niemeyer.net

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedSep 4, '13 at 5:54p
activeSep 4, '13 at 6:30p
posts4
users2
websitegolang.org

2 users in discussion

Luke Scott: 2 posts Gustavo Niemeyer: 2 posts

People

Translate

site design / logo © 2021 Grokbase