Using empty struct properly with CGO - go

Working with gssapi.h
struct gss_name_struct;
typedef struct gss_name_struct * gss_name_t;
I am trying to figure out how to properly initialize a variable containing this by
var output_name C.gss_name_t = &C.struct_gss_name_struct{}
But the functions like gss_import_name act like if I was passing null pointer to them. What is the correct way to properly initialize and use these empty structs with CGO?

Go's strict typing makes typedefs a pain to work with. The best way to make your Go look clear is to write a small wrapper function in C to build the struct exactly how you want it. In this case though, go is using a zero-length byte array for an empty C struct, which you can verify below. You can declare it directly in go, and convert it when necessary.
Since C isn't strict with types, using type inference is often the easiest way to assign the type that Go expects. There's also a trick using the cgo tool to show the type declarations you need. Using go tool cgo -godefs filename.go will output the cgo definitions for your types. As you see though, the go equivalent types could get a little messy.
// statement in the original .go file
//var output_name C.gss_name_t = &C.struct_gss_name_struct{}
// output from cgo -godefs
// var output_name *[0]byte = &[0]byte{}
// or more succinctly
output_name := &[0]byte{}
// output_name can be converted directly to a C.gss_name_t
fmt.Printf("%+v\n", output_name)
fmt.Printf("%+v\n", C.gss_name_t(output_name))

Related

Get the underlying type from a string in go? [duplicate]

Is there a way to use the reflection libraries in Go to go from the name of a type to its Type representation?
I've got a library where the user needs to provide Type representations for some code generation. I know it must be possible (in a sense) because they can just create a variable of that type and call the TypeOf function, but is there a way to circumvent this and just get representation from the name?
The question is not quite explicit, it can be interpreted in 2 ways, to one of which the answer is no, not possible; and the other to which the answer is yes, it's possible.
At runtime
If the type name is provided as a string value, then at runtime it's not possible as types that are not referred to explicitly may not get compiled into the final executable binary (and thus obviously become unreachable, "unknown" at runtime). For details see Splitting client/server code. For possible workarounds see Call all functions with special prefix or suffix in Golang.
At "coding" time
If we're talking about "coding" time (source code writing / generating), then it's possible without creating / allocating a variable of the given type and calling reflect.TypeOf() and passing the variable.
You may start from the pointer to the type, and use a typed nil pointer value without allocation, and you can navigate from its reflect.Type descriptor to the descriptor of the base type (or element type) of the pointer using Type.Elem().
This is how it looks like:
t := reflect.TypeOf((*YourType)(nil)).Elem()
The type descriptor t above will be identical to t2 below:
var x YourType
t2 := reflect.TypeOf(x)
fmt.Println(t, t2)
fmt.Println(t == t2)
Output of the above application (try it on the Go Playground):
main.YourType main.YourType
true

Access the raw bytes of a string

I'm trying to call a C function that expects a C string (char*) from go. I know about the C.CString function documented in the cgo documentation but as the function I'm calling will already make a copy, I'm trying to avoid the one Cstring makes.
Right now, I'm doing this, s being a go string
var cs *C.char = (*C.char)( unsafe.Pointer(& []byte(s) [0]))
But I get the feeling that the []bytes(s) is making its own copy. Is it possible to just get the char* ?
If you're doing this enough times that performance is a concern, it would really be advisable to keep the data in a slice to begin with.
If you really want to access to the address of the string, you can use the unsafe package to convert it into a struct matching the string header. Using the reflect.StringHeader type:
p := unsafe.Pointer((*(*reflect.StringHeader)(unsafe.Pointer(&s))).Data)
Or using a slice as a proxy, since they both put the data pointer and length integers in the same field locations
p := unsafe.Pointer(&(*(*[]byte)(unsafe.Pointer(&s)))[0])
Or because the data pointer is first, you could use a uintptr alone
p := unsafe.Pointer(*(*uintptr)(unsafe.Pointer(&s)))
https://play.golang.org/p/ps1Py7Ax6QK
None of these ways are guaranteed to work in all cases, or in future versions of Go, and none of the options are going to guarantee a null terminated string.
The best, supported option is to create a shim in the cgo preamble to accept the go string, and convert it to a *char. CGO provides access to the following function to do this:
const char *_GoStringPtr(_GoString_ s);
See the Go references to C section in the documentation.

Assigning types to variables in Go

How to have a variable whose type is a variable type?
What do I mean by that? I have a python and java background. In both languages I can do things like assigning a class name to variable.
#Python
class A:
def __init__(self):
self.a = "Some Value"
# And asigning the class name to a variable
class_A = A
# And create instance from class A by using class_A
a = class_A()
Is there such a mechanism in go that allows me to do that? I couldn't know where to look at for such things in their documentation. Honestly, generally I don't know what these are called in programming languages.
For example I would like to be able to do:
// For example, what would be the type of myType?
var myType type = int
I will use this mechanism to take "type" arguments. For example:
func Infer(value interface{}, type gotype) {...}
Is there such a mechanism in go that allows me to do that?
The short answer is: No.
The long answer is: This sounds like an XY Problem, so depending on what you're actually trying to accomplish, there may be a way. Jump to the end to see where I address your specific use-case.
I suspect that if you want to store a data type in a variable, it's because you either want to compare some other variable's type against it, or perhaps you want to create a variable of this otherwise unknown type. These two scenarios can be accomplished in Go.
In the first case, just use a type switch:
switch someVar.(type) {
case string:
// Do stringy things
case int:
// Do inty things
}
Semantically, this looks a lot like assigning the type of someVar to the implicit switch comparison variable, then comparing against various types.
In the second case I mentioned, if you want to create a variable of an unknown type, this can be done in a round-about way using reflection:
type := reflect.TypeOf(someVar)
newVar := reflect.New(type).Interface()
Here newVar is now an interface{} that wraps a variable of the same type as someVar.
In your specific example:
I will use this mechanism to take "type" arguments. For example:
func Infer(value interface{}, type gotype) {...}
No, there's no way to do this. And it actually has much less to do with Go's variable support than it does with the fact that Go is compiled.
Variables are entirely a runtime concept. Function signatures (like all other types in Go) are fixed at compilation time. It's therefore impossible for runtime variables to affect the compilation stage. This is true in any compiled language, not a special feature (or lack thereof) in Go.
Is there such a mechanism in go that allows me to do that?
No there is not.
Use the empty interface:
var x, y interface{}
var a uint32
a = 255
x = int8(a)
y = uint8(a)
Playground example

How to get Type representation from name via reflection?

Is there a way to use the reflection libraries in Go to go from the name of a type to its Type representation?
I've got a library where the user needs to provide Type representations for some code generation. I know it must be possible (in a sense) because they can just create a variable of that type and call the TypeOf function, but is there a way to circumvent this and just get representation from the name?
The question is not quite explicit, it can be interpreted in 2 ways, to one of which the answer is no, not possible; and the other to which the answer is yes, it's possible.
At runtime
If the type name is provided as a string value, then at runtime it's not possible as types that are not referred to explicitly may not get compiled into the final executable binary (and thus obviously become unreachable, "unknown" at runtime). For details see Splitting client/server code. For possible workarounds see Call all functions with special prefix or suffix in Golang.
At "coding" time
If we're talking about "coding" time (source code writing / generating), then it's possible without creating / allocating a variable of the given type and calling reflect.TypeOf() and passing the variable.
You may start from the pointer to the type, and use a typed nil pointer value without allocation, and you can navigate from its reflect.Type descriptor to the descriptor of the base type (or element type) of the pointer using Type.Elem().
This is how it looks like:
t := reflect.TypeOf((*YourType)(nil)).Elem()
The type descriptor t above will be identical to t2 below:
var x YourType
t2 := reflect.TypeOf(x)
fmt.Println(t, t2)
fmt.Println(t == t2)
Output of the above application (try it on the Go Playground):
main.YourType main.YourType
true

Is there any way to access private fields of a struct from another package?

I have a struct in one package that has private fields:
package foo
type Foo struct {
x int
y *Foo
}
And another package (for example, a white-box testing package) needs access to them:
package bar
import "../foo"
func change_foo(f *Foo) {
f.y = nil
}
Is there a way to declare bar to be a sort of "friend" package or any other way to be able to access foo.Foo's private members from bar, but still keep them private for all other packages (perhaps something in unsafe)?
There is a way to read unexported members using reflect (in Go < 1.7)
func read_foo(f *Foo) {
v := reflect.ValueOf(*f)
y := v.FieldByName("y")
fmt.Println(y.Interface())
}
However, trying to use y.Set, or otherwise set the field with reflect will result in the code panicking that you're trying to set an unexported field outside the package.
In short: unexported fields should be unexported for a reason, if you need to alter them either put the thing that needs to alter it in the same package, or expose/export some safe way to alter it.
That said, in the interest of fully answering the question, you can do this (and have to do it this way in Go >= 1.7)
func change_foo(f *Foo) {
// Since structs are organized in memory order, we can advance the pointer
// by field size until we're at the desired member. For y, we advance by 8
// since it's the size of an int on a 64-bit machine and the int "x" is first
// in the representation of Foo.
//
// If you wanted to alter x, you wouldn't advance the pointer at all, and simply
// would need to convert ptrTof to the type (*int)
ptrTof := unsafe.Pointer(f)
ptrTof = unsafe.Pointer(uintptr(ptrTof) + uintptr(8)) // Or 4, if this is 32-bit
ptrToy := (**Foo)(ptrTof)
*ptrToy = nil // or *ptrToy = &Foo{} or whatever you want
}
This is a really, really bad idea. It's not portable, if int ever changes in size it will fail, if you ever rearrange the order of the fields in Foo, change their types, or their sizes, or add new fields before the pre-existing ones this function will merrily change the new representation to random gibberish data without telling you. I also think it might break garbage collection for this block.
Please, if you need to alter a field from outside the package either write the functionality to change it from within the package or export it.
Edit2: Since you mention White Box testing, note that if you name a file in your directory <whatever>_test.go it won't compile unless you use go test, so if you want to do white box testing, at the top declare package <yourpackage> which will give you access to unexported fields, and if you want to do black box testing then you use package <yourpackage>_test.
If you need to white box test two packages at the same time, however, I think you may be stuck and may need to rethink your design.
I assume what you're testing is a package functionality that changes the state of that package's object, but you want to verify the internals post that change to affirm the new state is correct.
What might help would be writing Get and Set function for the private fields, so they can be accessed beyond the package scope.
package foo
type Foo struct {
x int
y *Foo
}
func (f *Foo) GetY() *Foo {
return f.y
}
func (f *Foo) SetY(newY *Foo) {
f.y = newY
}
Note that the idea of these Get and Set is to limit read and/or write access to the fields, while directly exporting them gives them read+write access automatically always. A subtle difference but worth consideration if the true goal is to only read the private fields and not operate on them (which the package internals would do in there own way)
Finally, if you're not comfortable with adding these type of wrappers for all the private fields in your package, then you can write them in a new file within that package and use build tags to ignore it in your regular builds, and include it in your test builds (wherever/however you trigger your testing).
// +build whitebox
// Get() and Set() function
go test --tags=whitebox
Regular builds ignore building test files along with them, so these wont come in your final binary. If this package is used elsewhere in entirely different ecosystem, then this file wouldn't be built still because of the build tags constraint.
I am just starting out with C++ -> Go porting and I ran across a pair of classes that were friends with each other. I am pretty sure if they are part of the same package they are friends by default, effectively.
The upper case first letter for an identifier is bound within the package. Thus they can be in separate files so long as they are in the same directory, and will have the ability to see each other's unexported fields.
Using reflect, even if it is Go stdlib, is something you should think always carefully about. It adds a lot of runtime overhead. The solution would be basically copy&paste if the two struct types you want to be friends, they simply must be in the same folder. Otherwise you have to export them. (Personally I think the woo woo about the 'risk' of exporting sensitive data is quite overblown, although if you are writing a solitary library that has no executable, maybe there can be some sense to this since users of the library will not see these fields in the GoDoc and thus not think they can depend on their existence).
Internal fields are in principle not exported from a package, which allows the author of a package to freely modify its internals without breaking any other package. Working around this using reflect or unsafe is not a good idea.
The language does deliberately not help you achieve what you want, so you're going to have to do it yourself. The simplest one is to simply merge the two packages — this is what Go unit tests typically do.
The alternative is to create an extra accessor that is only used by the bar package:
// SetYPrivate sets the value of y. This function is private to foo and bar,
// and should not be used by other packages. It might go away in future releases.
func (foo *Foo) SetYPrivate(y int) {
foo.y = y
}
An example of this technique is the runtime.MemStats function in the standard library, which returns a bunch of privates of the GC implementation.
There are multiple "hacks" to get there. One is using go:linkname. Another solution would be to have a public setter and inspect the stack trace.

Resources