Is there any quick and easy method of converting a struct to a byte array in D? I'm not really finding anything in the D docs.
void[] arr;
MyStruct s;
arr = (&s)[0..1];
Dynamic arrays of all types (constness still applies) implicitly convert to void[].
This builds for me:
struct Foo
{
int x;
}
void main()
{
Foo foo;
auto bytes = *(cast(byte[Foo.sizeof]*)(&foo));
}
auto byteArray = (cast(ubyte*) &myStruct)[0 .. myStruct.sizeof];
or to use union
union MyUnion {
MyStruct myStruct;
ubyte[MyStruct.sizeof] byteArray;
}
Related
I have a struct B which inherits from the struct A. I have another struct C (which contains a slice of structs A) and I want to append B to C.
package main
type A struct {
target string
}
type B struct{
A
values []int
}
type C struct{
Cols []*A
}
func main() {
var values = []int{1,2,3}
var col1 = C{}
var col2 = &B {
A: A{
target: "txt",
},
values: values,
}
col1.Cols = append(col1.Cols, col2)
}
When running this code, it generates an error: cannot use col2 (type *B) as type *A in append
What's wrong please ? I'm newer
Ps: sorry for my bad English
col1.Cols is type *A, col2 is type *B, col2.A is type A, if you want to add new element to the slices, they should be of the same type.
so if you change the last statement to
col1.Cols = append(col1.Cols, &col2.A)
it will work.
I defined a struct in C like:
struct SomeStruct
{
int var1;
bool var2;
double var3;
int var4[10];
int var5[10][10];
}
struct SomeStruct entity;
And somewhere there was a input box that some user input in GO:
func("entity.var3")
It will return value of entity.var3 in C struct.
Actually I could already implement it in python by cffi and:
def get_one_variable(buffer, setup):
value = buffer
for level in setup:
if isinstance(level, str):
value = getattr(value, level)
else:
[base, extends] = level
value = getattr(value, base)
for extend in extends:
value = value[extend]
return value
Where buffer is python cffi data pointer defined with "FFI.cdef" and setup resolved by:
def parse_variable(self, line):
line = line.replace('\n', '').replace(' ', '')
split = line.split('.')
variable = []
for child in split:
match = self.BASE_EXT_REGEX.match(child)
if match is None:
variable.append(child)
else:
base_name = match.group('base_name')
ext_name = match.group('ext_name')
variable.append([base_name, [int(index) for index in
ext_name.replace('[', ']').replace(']]', ']').strip(']').split(']')]])
return variable
So I can dynamically resolve "entity.var1", "entity.var2", "entity.var3", "entity.var4[0]", "entity.var5[0][1]".
Is there something or someway similar in GO?
This is handled by CGO which is a special package in Go that allows for easy C integration. You can read more about it here and here. Given your examples, a simple CGO example would be:
/*
struct SomeStruct
{
int var1;
bool var2;
double var3;
int var4[10];
int var5[10][10];
}
*/
import "C"
import "fmt"
func main(){
thing := C.struct_SomeStruct{}
thing.var1 = C.int(5)
fmt.Printf("My Struct's var field %d\n",int(thing.var1))
}
With GCC, I can do this:
typedef struct {
char a;
int n;
} MyStruct;
MyStruct ms __attribute__((section("MySection"))) = {'x', 33};
MyStruct *pms = &ms;
But when I use compound literal as follows, GCC complains warning: 'section' attribute does not apply to types [-Wattributes].
typedef struct {
char a;
int n;
} MyStruct;
MyStruct *pms = &(MyStruct __attribute__((section("MySection")))){'x', 33};
Is there any way to get by? Thank you.
I have following code for Golang docs parsing. "ts" is ast.TypeSpec. I can check StructType and etc. But, ts.Type is "int". How can I assert for int and other basic type?
ts, ok := d.Decl.(*ast.TypeSpec)
switch ts.Type.(type) {
case *ast.StructType:
fmt.Println("StructType")
case *ast.ArrayType:
fmt.Println("ArrayType")
case *ast.InterfaceType:
fmt.Println("InterfaceType")
case *ast.MapType:
fmt.Println("MapType")
}
The types in the AST represent the syntax used to declare the type and not the actual type. For example:
type t struct { }
var a int // TypeSpec.Type is *ast.Ident
var b struct { } // TypeSpec.Type is *ast.StructType
var c t // TypeSpec.Type is *ast.Ident, but c variable is a struct type
I find it's helpful to print example ASTs when trying to understand how different syntax is represented. Run this program to see an example.
This code will check for ints in most cases, but does not do so reliably:
if id, ok := ts.Type.(*ast.Ident); ok {
if id.Name == "int" {
// it might be an int
}
}
The code is not correct for the following cases:
type myint int
var a myint // the underlying type of a is int, but it's not declared as int
type int anotherType
var b int // b is anotherType, not the predeclared int type
To reliably find the actual types in the source, use the go/types package. A tutorial on the package is available.
I have some different structs like Big with Small embedded at offset 0.
How can I access Small's structure fields from code, that doesn't know anything about Big type, but it is known that Small is at offset 0?
type Small struct {
val int
}
type Big struct {
Small
bigval int
}
var v interface{} = Big{}
// here i only know about 'Small' struct and i know that it is at the begining of variable
v.(Small).val // compile error
It seems that compiler is theoretically able to operate such expression, because it knows that Big type has Small type embedded at offset 0. Is there any way to do such things (maybe with unsafe.Pointer)?
While answer with reflection is working but it has performance penalties and is not idiomatic to Go.
I believe you should use interface. Like this
https://play.golang.org/p/OG1MPHjDlQ
package main
import (
"fmt"
)
type MySmall interface {
SmallVal() int
}
type Small struct {
val int
}
func (v Small) SmallVal() int {
return v.val
}
type Big struct {
Small
bigval int
}
func main() {
var v interface{} = Big{Small{val: 3}, 4}
fmt.Printf("Small val: %v", v.(MySmall).SmallVal())
}
Output:
Small val: 3
Avoid using unsafe whenever possible. The above task can be done using reflection (reflect package):
var v interface{} = Big{Small{1}, 2}
rf := reflect.ValueOf(v)
s := rf.FieldByName("Small").Interface()
fmt.Printf("%#v\n", s)
fmt.Printf("%#v\n", s.(Small).val)
Output (try it on the Go Playground):
main.Small{val:1}
1
Notes:
This works for any field, not just the first one (at "offset 0"). This also works for named fields too, not just for embedded fields. This doesn't work for unexported fields though.
type Small struct {
val int
}
type Big struct {
Small
bigval int
}
func main() {
var v = Big{Small{10},200}
print(v.val)
}