为什么调C?
著名的开源库和性能。
- C代码可以写入到go文件中,要写在最前面,C代码用注释的写法,最后import C;
package main
// int add(int a, int b) {
// return a + b;
// }
import "C"
import "fmt"
func main() {
a := C.int(1)
b := C.int(2)
value := C.add(a, b)
fmt.Printf("%v\n", value)
fmt.Printf("%v\n", int(value))
}
- include头文件、动态链接库的写法:
1) 使用相对路径: #include "../header/header.h"
2) 使用库地址:
#cgo LDFLAGS: -L../../../../../shared/lib/ -lcloud_sdk_api
#cgo CFLAGS: -I../../../../../shared/inc/cloud_api/
#include "cloud_sdk_server_api.h"
3)文件放到一起: foo.h foo.c main.go(里面include "foo.h"即可)
- 数组指针的转换
go转C的*int:
in := []C.int{1, 2, 3, 4}
inPointer := unsafe.Pointer(&in[0])
inC := (*C.int)(inPointer) // *int
C的*int转go的slice:
outC := C.return_array_pointer(4)
defer C.free(unsafe.Pointer(outC))
sh := reflect.SliceHeader{uintptr(unsafe.Pointer(outC)), n, n}
out := *(*[]C.int)(unsafe.Pointer(&sh))
func CArrayToGoArray(cArray unsafe.Pointer, size int) (goArray []int) {
p := uintptr(cArray)
for i :=0; i < size; i++ {
j := *(*int)(unsafe.Pointer(p))
goArray = append(goArray, j)
p += unsafe.Sizeof(j)
}
return
}
CArrayToGoArray(unsafe.Pointer(&C.cArray[0]), 7)
- 访问C的结构体
C语言中的结构体类型在Go语言中的表现形式为C.struct_XXX
访问结构体 直接通过结构体变量.属性名称即可
package main
/*
#include <stdio.h>
struct Point {
float x;
float y;
};
*/
import "C"
import (
"fmt"
)
func main() {
// 1.利用C的结构体类型创建结构体
var cp C.struct_Point = C.struct_Point{6.6, 8.8}
fmt.Println(cp)
fmt.Printf("%T\n", cp)
// 2.将C语言结构体转换为Go语言结构体
type GoPoint struct {
x float32
y float32
}
var gp GoPoint
gp.x = float32(cp.x)
gp.y = float32(cp.y)
fmt.Println(gp)
}
- 字符串
package main
/*
void copy_date(char * src) {
int size = 0;
char ss[20];
size = strlen(src);
memcpy(ss, src, size);
printf("------------------:%s\n", ss);
}
*/
import "C"
import (
"fmt"
)
func main() {
C.copy_date(C.CString("20190522"));
// 1.C语言字符串转换Go语言字符串
str1 := C.str
str2 := C.GoString(str1)
fmt.Println(str2)
// 2.Go语言字符串转换C语言字符串
str := "lnj"
cs := C.CString(str)
C.say(cs)
// 注意: 转换后所得到的C字符串cs并不能由Go的gc所管理,我们必须手动释放cs所占用的内存
C.free(unsafe.Pointer(cs))
}
- C中使用Go函数
与在Go中使用C源码相比,在C中使用Go函数的场合较少。在Go中,可以使用"export + 函数名"来导出Go函数为C所使用
http://bastengao.com/blog/2017/12/go-cgo-c.html
https://tonybai.com/2012/09/26/interoperability-between-go-and-c/
https://www.jianshu.com/p/90f5d0a28326
有疑问加站长微信联系(非本文作者)