> I'm writing Go language bindings for a library using cgo and have some
> questions about wrapping structs. My questions are about the general
> function of Go so I put together the example below to help illustrate. I
> haven't been able to find a lot of documentation on cgo so I apologize for
> the numerous questions.
>
> 1. Will the expression *(*C.cobject)(obj)* allocate memory for a *C.cobject*pointer or just change the runtime type of
> *obj*?
It will just change the runtime type. It's like a cast in C.
> 2. Will the runtime recognize the type *wrapper.Object* as a C type and not
> move it in memory and/or deallocate it?
The runtime won't worry about pointers that point into spaces which the
runtime did not allocate, such as anything allocated using C's malloc.
Similarly, the runtime will not see anything allocated using C's malloc,
so any pointers from there to Go structures will not be seen and the Go
structures may be collected leaving the C pointers dangling. The
runtime won't move anything allocated using C's malloc.
> 3. Is it safe to deallocate an object's memory inside one of the object's
> methods?
Yes, you can deallocate the C object as long as you are careful to not
refer to the receiver after deallocating.
> 4. Why isn't there a panic when referencing *obj* after calling *Free()*, it
> returns an empty string?
When you use free, you become responsible for avoid dangling pointers
yourself. Free is an escape hatch from the protection mechanisms built
into Go.
> 5. Is this an efficient idiom or should I prefer using Go peer objects or
> something else? By peer I mean defining a Go struct for every C struct,
> declaring a member of the C type and the member to avoid type conversions.
What you are doing is efficient but it's easy to make a mistake. I
think that if I wanted methods on a C object using cgo I would use a Go
peer object as you describe.
Ian