Https://groups.google.com/forum/#!topic/golang-nuts/JkvR4dQy9t4
Https://golang.org/misc/cgo/gmp/gmp.go
Https://stackoverflow.com/questions/19910647/pass-struct-and-array-of-structs-to-c-function-from-go
https://studygolang.com/articles/6367
1. You can define a struct function for C struct, a print function defined as follows (you may also define a function that alters the inner child field of the struct, but I have not verified it):
Working with a lot of typedefs in CGO is a real pain (Go's typing rules are simply too strictfor a C programmer). I ' d suggest you create a wrapper function in C (or Go) to create the structure for you. For printing, where can define the String method on real type of structure (it won ' t be portable,as It depends the real type Name of the C struct, but it's certainly doable, and would save Youa lot of work if you ' re debugging a C-type-rich Applica tion) For example,
Package Main/*struct CType {int A; char b; float C;};*/Import"C"Import"FMT"func (c _ctype_struct_ctype) String ()string{return"Hello"} func Main () {FMT. Printf ("%v\n", c.struct_ctype{})}
One of the _ctype_struct_ctype chill to a bit strange, start without panic, you can use the following method to automatically get this strange naming.
Of course, the above only demonstrates defining built-in functions for C struct. If you are simply printing C struct in Golang, simply pass it on to print like a normal variable, such as FMT. Printf ("%v\n", c.objstruct) or fmt. Println (c.objstruct).
2, you can convert the entire Golang structure pointer to the C language of the structure of the pointer, provided that the structure of the Golang and C structure is one by one corresponding to the definition (there is a description of how to wear pieces one by one corresponding structure), but The struct pointer of the C language cannot be converted directly to the struct pointer of the Golang language :
You can cast the entire struct via intermediate pointers. The conversion should work in either direction. There is probably other ways too, like encoding/binary. An example of the pointer approach follows:
Package main Import ("FMT" "unsafe") //struct x {//int y, z;// };////int sum (struct x a) {//return a.y + a.z;// }//Import"C"type X struct{Y, Z Int32} Func main () {a:= &x{5,7} FMT. Println (A," -"C.sum(* (*c.struct_x) (unsafe. Pointer (a)))))
}
3, the second step of the practice is not safe, because the programmer's own definition of the Golang language structure May and C language structure does not correspond to one by one, so should use the following method:This isn't safe and Go doesn ' t guarantee compatible struct layout rules with GCC. For example, 8g currently aligns UInt64 only to 4-byte boundary, but GCC aligns it to 8-byte boundary. If you want compatible structure layout, you can use "Cgo-godefs". For example, given File.go:
/* #include <stdio.h> */ "C"
Go tool cgo-godefs File.go would generate a go definition of type file that matches that of C ' s file.
Cgo-godefs is a tool designed to convert C-language structures into structures that correspond to Golang languages.
4. Example:
Package Main/*#include <stdio.h>typedef struct {int A; int b;} Foo;void pass_struct (Foo *in) {printf ("%d:%d\n", In->a, in->b);} void Pass_array (Foo **in, int len) {for (int i = 0; i < len; i++) {pass_struct (in[i]); In[i]->a + = 1; In[i]->b + = 1; }}*/Import"C"Import ("FMT" "unsafe") Type Foo struct{A, b int32}func Main () {foo:= foo{Ten, -} Foos:= []*foo{&foo{1,2}, &foo{3,4}} FMT. Println ("From C Land") c.pass_struct (*c.foo) (unsafe. Pointer (&foo))) C.pass_array ((**c.foo) (unsafe. Pointer (&foos[0]), C.int(Len (Foos )))FMT. Println ("A & B should has incremented with 1") FMT. Println ("From Go Land") for_, Foo: =Range Foos {FMT. Printf ("%d:%d\n", FOO.A, FOO.B)}}
Output:
From C Land Ten - 1 2 3 4 1from Goland2345
5. Example 2:
Copy the char * pointer of the C language into the Golang byte slice:
//convert C language char* to Golang byte slice, and COPY source datas into Dest SlicePacket *c.Char //the variable is assigned in the C language.Vlen: = +B:= Make([]byte, Vlen) II:= C.int(0) forI: =0; i < Vlen; i++{II= C.int(i)//This was copy, not equal to the orignal pointerB[i] = * (*byte) (unsafe. Pointer (UIntPtr (unsafe. Pointer (packet)) +uintptr (unsafe. Pointer (C.int_to_charp (ii) )))}
Examples of my own conversions:
C language-defined structure:
struct Dnet_host { struct dnet_key key; Char Name[dnet_host_name_max]; Char version[]; time_t last_active; time_t last_appear; time_t last_time_changed; uint32_t CRC32; uint32_t route_ip; unsigned name_len; uint16_t Route_port; uint8_t is_local; uint8_t is_trusted; Enum dnet_host_route_types Route_type;};
Turn into a Golang corresponding structure (type DH c.struct_dnet_host):
type DH struct { Key _ctype_struct_dnet_key Name []int8 Version []int8 last_active Int64 last_appear Int64 last_time_changed Int64 CRC32 uint32 route_ip uint32 name_len uint32 route_port uint16 is_ Local uint8 is_trusted uint8 route_type uint32 pad_cgo_0 [4 ]byte}