1、Go -> C结构体
package main
/*
#include <>
#include <>
struct MyString
{
char* s;
int len;
};
struct MyString xmalloc(int len)
{
static const char* s = "0123456789";
char* p = malloc(len);
if (len <= strlen(s)) {
memcpy(p, s, len);
} else {
memset(p, 'a', len);
}
struct MyString str;
= p;
= len;
return str;
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func main() {
len := 10
str := ((len))
defer (())
gostr := (, )
("retlen=%v\n", )
println(gostr)
}
结果:
retlen=10
0123456789
你可以将整个golang的结构体指针转换成c语言的结构体指针,前提是golang 的结构体和c 的结构体定义是一一对应的(后面有介绍怎么穿件一一对应的结构体),但是c语言的结构体指针无法直接转换成golang语言的结构体指针:
package main
import (
"fmt"
"unsafe"
)
// struct x {
// int y, z;
// };
//
// int sum(struct x a) {
// return + ;
// }
//
import "C"
type X struct{ Y, Z int32 }
func main() {
a := &X{5, 7}
(a, "->", (*((*C.struct_x)((a)))))
}
cgo -godefs 是专门用来将c语言结构体转换成golang语言对应的结构体的工具。
package main
/*
#include <>
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{10, 20}
foos := []*Foo{&Foo{1, 2}, &Foo{3, 4}}
("from C land")
C.pass_struct((*)((&foo)))
C.pass_array((**)((&foos[0])), (len(foos)))
("a & b should have incremented with 1")
("from Go land")
for _, foo := range foos {
("%d : %d\n", , )
}
}
Output:
from C land
10 : 20
1 : 2
3 : 4
a & b should have incremented with 1
from Go land
2 : 3
4 : 5
2、Go -> C 整形指针
package main
/*
#include <>
#include <>
char* xmalloc(int len, int *rlen)
{
static const char* s = "0123456789";
char* p = malloc(len);
if (len <= strlen(s)) {
memcpy(p, s, len);
} else {
memset(p, 'a', len);
}
*rlen = len;
return p;
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func main() {
rlen := (0)
len := 10
cstr := ((len), &rlen)
defer ((cstr))
gostr := (cstr, rlen)
("retlen=%v\n", rlen)
println(gostr)
}
xmalloc函数的第二个参数是int*,这里设计为一个输入、输出参数。我们在Golang中使用类型的指针就可以;
其返回值是一个char*,在Golang中就是 *,由于返回值是指针,其内存由malloc分配,因此需要在Golang中对其内存进行释放。