cgo的踩坑记及一个简单的例子

这里写自定义目录标题

  • 1. 对照表
  • 2. 隐藏的坑
    • 2.1 嵌入式
    • 2.2 独立式

1. 对照表

首先,来看 golang 和 C 的类型转换对照表:

C语言类型 CGO类型 Go语言类型
char C.char byte
singed char C.schar int8
unsigned char C.uchar uint8
short C.short int16
unsigned short C.ushort uint16
int C.int int32
unsigned int C.uint uint32
long C.long int32
unsigned long C.ulong uint32
long long int C.longlong int64
unsigned long long int C.ulonglong uint64
float C.float float32
double C.double float64
size_t C.size_t uint

值得注意的是,C 中的整形比如 int 在标准中是没有定义具体字长的,但一般默认认为是 4 字节,对应 CGO 类型中 C.int 则明确定义了字长是 4 ,但 golang 中的 int 字长则是 8 ,因此对应的 golang 类型不是 int 而是 int32 。为了避免误用,C 代码最好使用 C99 标准的数值类型,对应的转换关系如下:

C语言类型 CGO类型 Go语言类型
int8_t C.int8_t int8
uint8_t C.uint8_t uint8
int16_t C.int16_t int16
uint16_t C.uint16_t uint16
int32_t C.int32_t int32
uint32_t C.uint32_t uint32
int64_t C.int64_t int64
uint64_t C.uint64_t uint64

2. 隐藏的坑

在Go中调用C一共有两种办法:

  • 第一种是将C代码直接嵌入到GO源文件中
  • 第二种是将C代码写在C文件中,再在GO文件中引入

2.1 嵌入式

第一种实现起来比较顺滑,如丝一般,但是没有进行分文件夹管理,看上去很不爽,同时也隐藏了一个坑,直接看一个栗子:

package main

/*
#include 

static int32_t add(int32_t a, int32_t b){
  return a+b;
}
*/
import "C"
import "fmt"

func main() {
  var a, b int32 = 1, 2
  c := int32(C.add(C.int32_t(a), C.int32_t(b)))
  fmt.Println(c)
}

如果在c代码与“import “C””之间留一个空行,直接报错如下:
cgo的踩坑记及一个简单的例子_第1张图片
去掉空行后就ok啦~,结果如下:
在这里插入图片描述

2.2 独立式

第二种实现实现起来坑就大大的了,no bb, 直接上栗子:
cgo的踩坑记及一个简单的例子_第2张图片

//foo.c
#include 

//int count = 6;
void foo() {
    printf("I am foo!\n");
}
//foo.h

int count = 6;
void foo();
package main

// #include 
// #include 
// #include "foo.h"
import "C"
import "fmt"

func main() {
  fmt.Println(C.count)
  C.foo()
}

佛曰:众生都是这么干的,一般分为两步:

  • 将C文件编译成动态链接库libfoo.so
  • 使用命令go build foo.go编译生成可执行文件

但在第二步的编译过程中会出现如下“对foo未定义的引用“的错误:
cgo的踩坑记及一个简单的例子_第3张图片
于是乎,赶紧引经据典,经过一番折腾之后,在https://groups.google.com/forum/#!topic/golang-nuts/O4RTszIyL7c最终找到了答案:

我们不需要手动地给go提供动态链接库,甚至于go根本不认识我们自己手动编译出的动态链接库。其实cgo提供了一种机制:它能够根据import”C”中引入的头文件,自动找到相应的源文件进行编译链接。这种机制的调用,需要用到go build命令。

输出结果如下:
cgo的踩坑记及一个简单的例子_第4张图片
佛曰:众生皆幻象,众生皆平等!

你可能感兴趣的:(技术类,golang,c,cgo,踩坑记,对照表)