2.7 KiB
2.7 KiB
CGO 的基本使用
Go 调用 C
内联编码
package main
/*
#include <stdio.h>
int test() {
return 2016;
}
*/
import "C"
import "fmt"
func main() {
fmt.Println(C.test())
}
编译命令如下:
CGO_ENABLED=1 CC=gcc go build
静态链接
C 代码写在 .c 和 .h 独立文件中,与 Go 代码共同编译。
/**
* @file: demo.h
*/
#ifndef DEMO_H
#define DEMO_H
#include <stdint.h>
__attribute__ ((visibility("default"))) extern int32_t test003_init(int32_t i);
#endif // DEMO_H
/**
* @file: demo.c
*/
#include "demo.h"
int32_t test003_init(int32_t i) {
return i*i;
}
main.go 如下:
package main
/*
#cgo CFLAGS : -I./
#include "demo.h"
*/
import "C"
import "fmt"
func main() {
i := C.test003_init(C.int(3))
fmt.Println(i)
fmt.Println("Hi")
}
编译命令如下:
CGO_ENABLED=1 CC=gcc go build
动态链接
C 代码写在 .c 和 .h 独立文件中,与 Go 代码分开编译。
/**
* @file: demo.h
*/
#ifndef DEMO_H
#define DEMO_H
#include <stdint.h>
__attribute__ ((visibility("default"))) extern int32_t test003_init(int32_t i);
#endif // DEMO_H
/**
* @file: demo.c
*/
#include "demo.h"
int32_t test003_init(int32_t i) {
return i*i;
}
先将 C 代码编译成共享库,编译命令如下:
gcc -shared -o libdemo.so demo.c
main.go 如下:
package main
/*
#cgo CFLAGS : -I./
#cgo LDFLAGS: -L./ -ldemo
#include "demo.h"
*/
import "C"
import "fmt"
func main() {
i := C.test003_init(C.int(3))
fmt.Println(i)
fmt.Println("Hi")
}
再编译 Go 代码:
CGO_ENABLED=1 CC=gcc go build
CGO 中的类型
基础类型
C.char
C.schar(signed char)
C.uchar(unsigned char)
C.short
C.ushort(unsigned short)
C.int
C.uint(unsigned int)
C.long
C.ulong(unsigned long)
C.longlong(long long)
C.ulonglong(unsigned long long)
C.float
C.double
nil <-> NULL
Go string 转 C string
func C.CString(goString string) *C.char
转换为 C string 会分配一个内存,因此需要释放,文档中示例如下
// #include <stdlib.h>
import "C"
import "unsafe"
...
var cmsg *C.char = C.CString("hi")
defer C.free(unsafe.Pointer(cmsg))
// do something with the C string
C string 转 Go string
func C.GoString(cString *C.char) string
func C.GoStringN(cString *C.char, length C.int) string
C 调用 Go
参考 Build and Use Go Packages as C Libraries
注意事项
- Go 调用 C 时,CGO 的注释和 import “C” 之间不能有空行,否则出现“could not determine kind of name for C.xxxxx” 等莫名奇妙的错误。