Golang 调用 C/C++ 库

作者: adm 分类: go 发布时间: 2022-09-02

目录结构:

|-importC
|  |-lib
|  |  |-libvideo.dll
|  |  |-libvideo.so
|  |-include
|  |  |-video.h
|  |  |-video.c
|  |-main.go

C的代码如下:
头文件 video.h

//video.h
#ifndef VIDEO_H
#define VIDEO_H
void exeFFmpegCmd(); // 声明
int sum(int a,int b);
#endif

源文件 video.c

#include 
#include "video.h"
 
void exeFFmpegCmd(){ // 实现
    printf("finish");
}
 
int sum(int a,int b){
    return (a+b);
}

编译:使用 gcc 或 g++ 生成 .so库,或 win 下生成 dll, 将.so库放到lib目录下(可以任意放,但在go的代码中要能找到)

命令:

gcc video.c -fPIC -shared -o libvideo.so

go的代码:

package main
 
/*
#cgo CFLAGS: -Iincludes
#cgo LDFLAGS: -Llib -lvideo -lstdc++
#include "video.h"
*/
import "C"
import "fmt"
 
func main() {
	C.exeFFmpegCmd()
	GoSum(5,6)
}
 
func GoSum(a,b int) {
	s := C.sum(C.int(a),C.int(b))
	fmt.Println(s)
}
CFLAGS中的-I(大写的i) 参数表示.h头文件所在的路径
LDFLAGS中的-L(大写) 表示.so文件所在的路径 -l(小写的L) 表示指定该路径下的库名称,比如要使用libhi.so,则只需用-lhi (省略了libhi.so中的lib和.so字符)表示。

CFLAGS对应C语言特有的编译选项、
CXXFLAGS对应是C++特有的编译选项、
CPPFLAGS则对应C和C++共有的编译选项

LDFLAGS 对应库.so链接选项

C 数值类型与 Go 中的访问类型对应关系

C 类型名称

Go 类型名称
char C.char
signed char C.schar
unsigned char C.uchar
short C.short
unsighed short C.ushort
int C.int
unsigned int C.uint
long C.long
unsigned long C.ulong
long long C.longlong
unsigned long long C.ulonglong
float C.float
double C.double
complex float C.complexfloat
complex double C.complexdouble
void* unsafe.Pointer
__int128_t   __uint128_t [16]byte

常见问题:
问题1:

./main: error while loading shared libraries: libvideo.so: cannot open shared object file: No such file or directory

直接度娘 error while loading shared libraries,就会知道其实就是没有找到这个动态库,我们编辑:

vim /etc/ld.so.conf 文件,将我们的路径写在该文件下,如图,编辑好后执行:ldconfig


问题2:

./include/check-reg.h:4:18: fatal error: glib.h: No such file or directory
 #include 
                  ^
compilation terminated.

由于在头文件中 #include 导入了glib.h,go build时报错,找不到

解决: 首先确保系统安装了glib-2.0, sudo apt-get install libglib2.0-dev

然后在命令行执行 pkg-config –cflags glib-2.0,找到glib的获取编译器标志

在go代码CFLAGS中告诉cgo在使用gcc编译时,glib的依赖在哪里

package main
 
 
/*
#cgo CFLAGS: -Iinclude -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
#cgo LDFLAGS: -L${SRCDIR}/lib -lreg-check
#include "check-reg.h"
*/
import "C"
import (
	"fmt"
	"net"
	"encoding/json"
 
)

使用CGO的项目交叉编译问题
————————————————

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!