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.
Related
package main
/*
#include <inttypes.h>
#pragma pack(1)
typedef struct _sss {
uint64_t some; // ok
uint32_t wow; // ok
uint64_t some2; // not found
uint64_t some3; // not found
uint64_t some4; // not found
uint32_t some5; // ok
} Type;
#pragma pack()
*/
import "C"
import (
"fmt"
)
func main() {
s := C.Type{}
s.some = 10;
s.wow = 10;
s.some2 = 10;
s.some5 = 10;
fmt.Println("Hello, playground")
}
I declared struct named C.Type.
If pragma pack(1) and 64 bits members are used together.
╭─dire#dire-81w4 ~/workspace
╰─go run test.go 2 ↵
# command-line-arguments
./test.go:25:6: s.some2 undefined (type _Ctype_struct__sss has no field or method some2)
Compilation is possible by removing pragma pack(1).
Go 1.15 version is being used. Do you know why?
I found answer about my question.
If the fields of a C struct are aligned such that they can't be represented by a Go struct, then they cannot be accessed directly from cgo. You will have to write functions in C to read and write those fields.
I nowdays am too busy to comment. It's late, but it's answered.
c.h
typedef void* MVar;
C_FUNC(
MVar* myvar //[out], return value
)
test.go
var cvar unsafe.Pointer
_ = C.C_FUNC(&cvar)
when I run test.go, it tells me
cannot use _cgo5 (type *unsafe.Pointer) as type *_Ctype_MVar
in argument to _Cfunc_C_FUNC
In this document Command cgo: Go references to C, it says "The C type void* is represented by Go's unsafe.Pointer."
cannot use _cgo5 (type *unsafe.Pointer) as type *_Ctype_MVar
in argument to _Cfunc_C_FUNC
The Go toolchain says you have a type mismatch.
An equivalent, working example, with matching types,
package main
import (
"fmt"
"unsafe"
)
/*
typedef void* pv_t;
void cfunc(pv_t *p);
#include <stdio.h>
int i;
void cfunc(pv_t *p) {
i = 42;
*p = &i;
printf("%p %p %d\n", p, *p, *(int*)(*p));
}
*/
import "C"
func main() {
var cptr unsafe.Pointer
C.cfunc((*C.pv_t)(&cptr))
fmt.Println(&cptr, cptr, *(*C.int)(cptr))
}
Output:
$ go run so.go
0xc000010028 0x592d18 42
0xc000010028 0x592d18 42
$
This is a C struct that I want to port into Go struct:
struct InputBuffer_t {
char* buffer;
size_t buffer_length;
ssize_t input_length;
};
But there is a way to declare buffer_length variable without using C.size_t cgo pointer in Go.
This is a concern for portability. If I write the Go struct in this way, is it will be portable?
type InputBuffer struct {
Buffer string
BufferLength uint32
InputLength uint32
};
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.
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;
}