-
Notifications
You must be signed in to change notification settings - Fork 18
/
main.go
52 lines (40 loc) · 1.29 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package main
// Go语言调用C函数例子
// 注意: 引用的C头文件需要在注释中声明,紧接着注释需要有import "C",且这一行和注释之间不能有空格
/*
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void myprint(char* s) {
printf("%s\n", s);
}
static int add(int a,int b){
return a+b;
}
*/
import "C"
import (
"fmt"
"runtime"
"unsafe"
)
func main() {
// func C.CString(string) *C.char 将go的字符串转换为C语言的char*类型。
cs := C.CString("Hello World\n")
C.myprint(cs)
// C.add 会被转为 _Cfunc_add 调用
v,err := C.add(1,2)
fmt.Println(v,err)
// C.CString 返回的空间由C语言的malloc分配,使用完毕后需要用free释放。
// C语言的free参数是void*类型,对应go语言的unsafe.Pointer。
defer C.free(unsafe.Pointer(cs))
fmt.Println("call C.sleep for 3s")
C.sleep(3)
// 当前进程执行的cgo调用次数
println("当前进程调用c方法的次数:", runtime.NumCgoCall())
}
/*
分析:
需要将Go的字符串传入C语言时,先通过C.CString将Go语言字符串对应的内存数据复制到新创建的C语言内存空间上。上面例子的处理思路虽然是安全的,
但是效率极其低下(因为要多次分配内存并逐个复制元素),同时也极其繁琐
*/