one way using cgo: you may access any fields of C struct, using var s *C.struct_tagA = &C.N or simply using s := &C.N like this working sample code:

package main

/*
#include <string.h>
#include <stdint.h>
typedef struct tagA {
    int64_t a;
    int64_t b;
    char  c[1024];
}A;

A N={12,22,"test"};
*/
import "C"

import "fmt"

type A struct {
    a int64
    b int64
    c [1024]byte
}

func main() {
    s := &C.N // var s *C.struct_tagA = &C.N

    t := A{a: int64(s.a), b: int64(s.b)}
    length := 0
    for i, v := range s.c {
        t.c[i] = byte(v)
        if v == 0 {
            length = i
            break
        }
    }

    fmt.Println("len(s.c):", len(s.c)) // 1024
    str := string(t.c[0:length])       
    fmt.Printf("len:%d %q \n", len(str), str) // len:4 "test" 

    s.a *= 10
    fmt.Println(s.a) // 120

}

output:

len(s.c): 1024
len:4 "test" 
120

you may use s.a , s.b and s.c directly in Golang. you do not need to copy all of it.

Answer from user6169399 on Stack Overflow
🌐
Google Groups
groups.google.com › g › golang-nuts › c › JkvR4dQy9t4
cgo - cast C struct to Go struct
Using cgo, I have a function that returns a C struct, and I can cast the fields to print them out from Go: urip := C.gnet_snmp_parse_uri(curi, &gerror) fmt.Printf("urip: %v\n", urip) fmt.Printf("scheme: %s\n", C.GoString((*C.char)(urip.scheme))) urip: &{0x7f1e54000960 0x7f1e54000980 0x7f1e540009a0 161 [0 0 0 0] 0x7f1e540009c0 <nil> <nil>} scheme: snmp Rather than manually casting every field, is there an easier way to cast all the fields at once, or convert the C struct to a Go struct? urip is this C struct: typedef struct _GURI GURI; struct _GURI { gchar* scheme; gchar* userinfo; gchar* hostname; gint port; gchar* path; gchar* query; gchar* fragment; }; (Out of interest, the C code is from gsnmp and gnet-2.0/uri.h) -- Sonia
Discussions

go - golang struct with C struct in CGO - Stack Overflow
I will use cgo to wrap one c library as go library for the project usage. I read the document, it seems there are lots of rules while using cgo. I don't know whether this is legal or not. Both Li... More on stackoverflow.com
🌐 stackoverflow.com
cgo - Pass struct and array of structs to C function from Go - Stack Overflow
However I would say that is a recipe for trouble - make your Go and C code use the same structure with ... Sign up to request clarification or add additional context in comments. ... Agree with your conclusion about using the C type explicitly. Just a note, golang's int is not necessarily 64bit; ... More on stackoverflow.com
🌐 stackoverflow.com
"casting" the raw bytes of a C-struct into a Go struct
check out binary.Read and binary.Write. You'll also have to specify the endianness. More on reddit.com
🌐 r/golang
10
12
March 21, 2022
cgo - Good or recommended way to translate C struct to Go struct - Stack Overflow
i'm using cgo for developing library binding from Go. Let me consider the C struct and Go Struct as below. struct cons_t { size_t type; cons_t *car; cons_t *cdr; }; cons_t* parse(const char... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Go Forum
forum.golangbridge.org › getting help
Pass a populated GO structure from GO source file to C : ctogo - Getting Help - Go Forum
November 15, 2017 - Am trying to send a GO structure from from GO code to a C code and access the content of GO structure in C. I was able to pass a GO int from GO code to C and access the GO int in C and also was able to modify, but am facing issues in passing a GO structure to C. Below is the code snippet. go_func.go package main import ( /* #include "cmain.h" */ "C" "fmt" ) type test struct { first_name string last_name string } func main() { var p test p.first_na...
🌐
14rcole
14rcole.github.io › post › cgo-part1-structs
Best Practices in cgo Part I: Structs | Ryan Cole
April 20, 2016 - The first is to create a struct that only contains a pointer · package person import ( "fmt" ) // #include "../structs.h" import "C" type CPerson struct { ptr unsafe.Pointer } func (cp CPerson) CPersonToNative() *C.Person { return cp.ptr } func NewCPerson(p unsafe.Pointer) CPerson { var cp CPerson cp.ptr = p return CPerson } func PrintPerson() { p := GetPerson() fmt.Println("name:", C.GoString(p.name)) fmt.Println("age:", p.age) } func GetPerson() CPerson { p := NewCPerson(unsafe.Pointer(C.new_person())) p.name = C.CString("John Doe") p.age = 39 return p }
🌐
Narkive
golang-nuts.narkive.com › Qy6vqksh › how-to-cast-a-go-struct-to-c-struct-through-cgo
How to cast a go struct to c struct through cgo?
./test.go:8: error: invalid application of 'sizeof' to incomplete type 'struct Key' cgo doesn't support using Go types in C code (cgo is about using existing C code in Go). Normally, you just define the structure in C, and use it in Go. -- You received this message because you are subscribed ...
🌐
Medium
medium.com › @liamkelly17 › working-with-packed-c-structs-in-cgo-224a0a3b708b
Working with Packed C Structs in cgo | by Liam Kelly | Medium
May 15, 2020 - C struct fields are allocated along memory bounds by default so that memory calls are faster, but this comes at the cost of potentially wasting some memory. For most developers, this is normally an acceptable tradoff; however, there are some ...
Find elsewhere
🌐
Medium
saeed0x1.medium.com › go-struct-vs-c-struct-4faa36e1af5b
Go struct vs C struct. In this article we’ll discuss about the… | by SAEED | Medium
March 3, 2023 - In C, we can define functions that take a struct as an argument, but these functions are not associated with the struct in the same way as methods. ... In C, we can initialize a struct using a syntax similar to an array initialization.
🌐
Reddit
reddit.com › r/golang › "casting" the raw bytes of a c-struct into a go struct
r/golang on Reddit: "casting" the raw bytes of a C-struct into a Go struct
March 21, 2022 -

Hi all,

New gopher here. I am writing the server side of a client/server application. Previous server was using Python, specifically the ctypes module, to convert the received data from the C client into the Python equivalent. The C struct looks something like this:

#pragma pack(1)
typedef struct _DATA {
    uint32_t ID;
    uint32_t NameLen;
    wchar_t Name[];     // Variable, depends on NameLen.
} DATA;

In Python I would receive the raw bytes from the network, and "cast" them into the appropriate equivalent using ctypes. I know Go has cgo, and I've read this article, but it's not exactly my use case and I'm kind of stuck.

Essentially I want to read the raw bytes of the C struct from the network, convert them to the Go equivalent, parse/handle them, then reverse the process.

I'm fairly certain what I'm trying to do is possible in Go, but I'm pretty new to it and unfamiliar with what I should be looking into. Using a different format like JSON, etc. is not at option due to overhead and not controlling the client.

Thanks!

🌐
GitHub
github.com › AlekSi › cgo-by-example › blob › master › main.go
cgo-by-example/main.go at master · AlekSi/cgo-by-example
July 3, 2018 - s1 := C.struct_s1{a: 5} // or cast with C.int: s1 := C.struct_s1{C.int(i)} s1Ret := C.f31(s1) fmt.Printf("f31: s1=%v, s1Ret=%v\n", s1, s1Ret) · // Pass C struct to C function by pointer. s1 = C.struct_s1{a: 5} s1Ret = *C.f32(&s1) fmt.Printf("f32: s1=%v, s1Ret=%v\n", s1, s1Ret) ·
Author   AlekSi
🌐
Google Groups
groups.google.com › g › golang-nuts › c › en5U5bQXbDE
Wrapping a C struct using a Go type alias
> 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.
Top answer
1 of 2
3

You can use C structs in Go (though if the struct holds a union it gets a bit more complex). The simplest way would just be

type Cons struct {
    c C.cons_t
}

Any function in C is now just a passthrough in Go

func Parse(s string) Cons {
    str := C.CString(s)
    // Warning: don't free this if this is stored in the C code
    defer C.free(unsafe.Pointer(str))
    return Cons{c: C.parse(str)}
}

This has its own overhead, since you have to do a type conversion on element access. So what was before var c Cons{}; c.Type is now

func (c Cons) Type() int {
    return int(c.c.type)
}

An intermediate compromise can be used where you store fields alongside the C type for easy access

type Cons struct {
    type int
    c C.cons_t
}

func (c *Cons) SetType(t int) {
    c.type = t
    c.c.type = C.size_t(t)
}

func (c Cons) Type() int {
    return c.type
}

The only real problem with this is that if you're calling C functions a lot, this can introduce maintenance overhead in setting the Go-side fields:

func (c *Cons) SomeFuncThatAltersType() {
    C.someFuncThatAltersType(&c.c)
    c.Type = int(c.c.type) // now we have to remember to do this
}
2 of 2
2

I would recommend against the accessor functions. You should be able to access the fields of the C struct directly, which will avoid the Go -> C function call overhead (which is non-trivial). So you might use something like:

func TranslateCCons2GoCons (c *C.cons_t) *Cons {
    if c == nil {
        return nil
    }
    return &Cons{
        type: int(c.type),
        car: TranslateCCons2GoCons(c.car),
        cdr: TranslateCCons2GoCons(c.cdr),
    }
}

Also, if you allocate a C string with C.CString, you need to free it. So your Parse function should look something like:

func Parse (str string) *Cons {
    str_ptr := C.CString(str)
    defer C.free(unsafe.Pointer(str_ptr)
    cons_ptr := C.parse(str_ptr)
    retCons := TranslateCCons2GoCons(cons_ptr)
    // FIXME: Do something to free cons_ptr here.  The Go runtime won't do it for you
    return retCons
}
🌐
Hacker News
news.ycombinator.com › item
Getting C-compatible structs in Go with and for cgo | Hacker News
August 31, 2015 - When I asked about why going cgo instead, the general reaction was "go away we know better", as usual · EDIT: Typo (way => away)
🌐
YourBasic
yourbasic.org › golang › structs-explained
Create, initialize and compare structs · YourBasic Go
The new keyword can be used to create a new struct. It returns a pointer to the newly created struct. var pa *Student // pa == nil pa = new(Student) // pa == &Student{"", 0} pa.Name = "Alice" // pa == &Student{"Alice", 0} You can also create ...
🌐
Karthikkaranth
karthikkaranth.me › blog › calling-c-code-from-go
Calling C code from go | Karthik Karanth
The only differences are in how we created a struct, and how we called the function. We can access any C struct using C.struct_ followed by the name of the struct. We can then initialize the members as we would in a normal go struct.
🌐
Go Packages
pkg.go.dev › cmd › cgo
cgo command - cmd/cgo - Go Packages
April 7, 2026 - A few special C types which would normally be represented by a pointer type in Go are instead represented by a uintptr. See the Special cases section below. To access a struct, union, or enum type directly, prefix it with struct_, union_, or enum_, as in C.struct_stat.