在golang里调用c
Index
Intro
golang有一个贼牛的东西叫做cgo,这个可以让你在golang里运行c, 当然也可以调用c的library,总之就是很牛皮
cgo 官方文档: https://pkg.go.dev/cmd/cgo
使用方法
这边简单说一下golang里调用c的基本方法
基本
我们首先来看一下最简单的hello world.
- 如果要使用c, 首先需要
import "C"
, 并且在这行代码的上面要加上对应的c code, 比如引入头文件, 定义一些函数之类的 - 调用C的函数的话就用
C.<function name>
, 但是要注意的是,返回的值都是C的类型。 如果要把他变成golang的类型,需要进行转换 - 调用C的函数的话,传入的参数同样必须为C的类型
1 | package main |
如何引入外部的C文件
比如,我有一个c文件
a.c
1 |
|
a.h
1 | void println(char * s); |
那么要在golang里调用的话就是
1 | package main |
调用第三方库
这里以调用libmpv
为例子.
注意mpv/client.h
以及对应的库文件(mpv-2.dll
或者libmpv.so
)必须在PATH环境变量中。
如果不在的话,需要修改LDFLAGS #cgo LDFLAGS: -L./lib -lmpv
1 | /* |
踩坑
不同的系统有不同的Primitive data
比如
在windows上,uint64
或者说 long
他的大小是 4 byte.
但是在unix/linux上, uint64
的大小是 8 byte.
这就导致了一些问题,比如我有一个项目需要同时支持两个系统,那么当我想传入uint64
的时候,在windows上得用ulong
,在linux上就得用 ulonglong
.
解决方式就是使用引入stdint.h
然后使用 uint64_t
.
1 | /* |
常见问题
Q: 遇到unexpected type: ...
是怎么回事呢
...
在c里面代表可变的函数参数,但是cgo无法识别他,所以会报错。解决方法就是写一个函数,在c里面调用这个函数,给golang的函数里就不要出现可变的部分了
举个例子, 比如以下情况就会出现这个报错,因为printf 里有个可变部分。int printf(const char *format, ...)
1 | /* |