一、编译和链接参数
1、编译参数:CFLAGS/CPPFLAGS/CXXFLAGS
编译参数主要是头文件的检索路径、预定义的宏等参数。CFLAGS:对应c语言编译参数(*.c),CPPFLAGS对应c/c++代码编译参数(*.c/*.cc/*.cpp/*.cxx),
CXXFLAGS对应纯C++编译参数(*.cc/*.cpp/*.cxx)。
2、链接参数:LDFLAGS
链接参数主要包含链接库的检索目录和链接库的名字。链接库不支持相对路径,必须为链接库指定决定路径。CGO中的$(SRCDIR)为当前目录的决定路径。
3、pkg-config
#cgo pkg-config XXX命令来生成XXX库需要的编译和链接参数,其底层通过pkg-config xxx -cflags 命令生成编译参数,通过pkg-config xxx --libs命令生成
链接参数。
二、静态库和动态库
1、导出c静态库
根据CGO文档的要求,需要在main包中导出C函数。对C静态库构建方式来说,会忽略main包中的main()函数,只是简单导出C函数。使用如下命令:
go build -buildmode=c-archive -o number.a
在生成number.a静态库的同时,CGO还会生成一个number.h文件。
go build会忽略用下划线作为前缀名的文件。
2、导出c动态库
和导出c静态库类似,只要将c-archive修改为c-shared
3、导出非main包的函数
要实现从非main包导出C函数,或者从多个包导出C函数,需要提供导出C函数对应的头文件(因为CGO无法为非main包的导出函数生成文件)。
三、CGO内存模型
简介:CGO是架接GO和C的桥梁,使两者在二进制接口层面实现了互通,但是两个有明显的差异。GO语言和C语言共享某一段内存的场景,C语言的内存
在分配之后是稳定的,但是Go语言的函数栈的动态伸缩可能导致栈中内存地址的移动。如果C语言只有的是移动之前的Go指针,那么以旧指针访问Go对象
时会导致程序崩溃。
1、Go访问C内存