当前位置:   article > 正文

golang调用c语言动态库和静态库,cgo(二)_golang链接静态库

golang链接静态库

C语言动态库,就是在编译的时候使用enable-shared,最终会生成.so文件。

第三方动态库库

此处以 lzo 库为例,他是用C语言写的用来压缩文件的库。以编译的方式来安装。

> cd /usr/local

> wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.10.tar.gz

> tar -xzf lzo-2.10.tar.gz

> cd /usr/local/lzo-2.10

> ./configure --enable-shared

> make && make install

从输出的信息看,lzo库被安装在了 /usr/local/lib

将库文件复制至/usr/lib,如果是64位系统则是 /usr/lib64
> cp /usr/local/lib/*lzo* /usr/lib64/

否则会在后续执行lzop命令时出现类似如下的提示 lzop: error while loading shared libraries: liblzo2.so.2: cannot open shared object file: No such file or directory

> ls /usr/lib64/*lzo*
/usr/lib64/liblzo2.a  /usr/lib64/liblzo2.la  /usr/lib64/liblzo2.so  /usr/lib64/liblzo2.so.2  /usr/lib64/liblzo2.so.2.0.0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
package main

/*
#cgo LDFLAGS: -llzo2
#include <lzo/lzo1x.h>
*/
import "C"
import "fmt"

func main() {
	fmt.Println(uint16(C.lzo_version())) // 8288
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

#cgo LDFLAGS: -llzo2 表示要连接 /usr/lib64下面的liblzo2.so.2,其中.so.2为动态库的版本号,它是在库的接口发生变化时更新的

使用尖括号<lzo/lzo1x.h>,那么预处理器会在/usr/local/include 与 /usr/include目录下来搜索对应的头文件,上述编译安装已将这些头文件安装在了/usr/local/include/lzo

> ls /usr/local/include/lzo
lzo1a.h  lzo1b.h  lzo1c.h  lzo1f.h  lzo1.h  lzo1x.h  lzo1y.h  lzo1z.h  lzo2a.h  lzo_asm.h  lzoconf.h  lzodefs.h  lzoutil.h
  • 1
  • 2

我们打开lzo1x.h文件就可以看到其定义了哪些函数,当然想要用好这个库,我们还是要对它有一定的了解。

对于命令中用双引号指定的文件(“文件名.h”),预处理器通常首先在当前目录下寻找,也就是包含该程序其他源文件的目录。如果在当前目录下没有找到,那么预处理器也会搜索系统的 include 路径。

自定义动态库库

./number/number.h

int number_add_mod(int a, int b, int mod);
  • 1

./number/number.c

#include "number.h"

int number_add_mod(int a, int b, int mod)
{
    return (a + b) % mod;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

生成./number/libnumber.so

cd ./number
gcc -fPIC -shared -o libnumber.so number.c
  • 1
  • 2
package main

/*
#cgo LDFLAGS: -L./number -lnumber -Wl,-rpath,number
#include "number/number.h"
*/
import "C"
import "fmt"

func main() {
	fmt.Println(C.number_add_mod(3, 2, 2))
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

-L 的意思是将后面的这个目录包含进链接库检索范围。

#include后面使用双引号,可以加上目录,或者使用 *#cgo CFLAGS: -I./number*来指定目录。

> go run main5.go
1
  • 1
  • 2

如果出现报错

error while loading shared libraries: libnumber.so: cannot open shared object file: No such file or directory
  • 1

那就是没有指定目录,或者找不到文件。

调用静态库

生成静态库

libnumber.so libnumber.xxx

cd ./number
gcc -c -o libnumber.o number.c
ar rcs libnumber.a libnumber.o
  • 1
  • 2
  • 3
  • 4
  • 5

生成libnumber.a静态库之后,我们就可以在CGO中使用该资源了。代码和上面一样,直接运行即可。

package main

/*
#cgo LDFLAGS: -L./number -lnumber -Wl,-rpath,number
#include "number/number.h"
*/
import "C"
import "fmt"

func main() {
	fmt.Println(C.number_add_mod(3, 2, 2))
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
> go run main6.go
1
  • 1
  • 2
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/173726
推荐阅读
相关标签
  

闽ICP备14008679号