cgo通过动静态库调用c/c++

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a1368783069/article/details/84238743

1 动静态库的区别

可以参考: C++静态库与动态库 https://www.cnblogs.com/skynet/p/3372855.html

概括:
动静态库区别总结:
1 链接方式不一样。调用阶段不同动态库在程序运行的时候进行调用,静态库在链接阶段将汇编文件与引用到的库一起链接生成可执行文件。因此前者生成的可执行文件较后者小。 同时,当库文件改变时,动态库只需要重新编译库文件,而静态库需要编译所有文件。

2 库文件的搜索路径不一样。 具体参考: ld搜索路径顺序 https://blog.csdn.net/fightingform/article/details/47302415
或者在网站找相关资料,此处不作说明。

2编译动静态库

假设有一下目录结构及文件

example
   - main.go
   - temp
     -  test.h
     - test.cpp
//test.h
#ifndef TEST_H  
#define TEST_H  
#ifdef __cplusplus  
extern "C"
{
#endif
int add (int a,int b);
#ifdef __cplusplus  
}
#endif
#endif
// test.cpp
#include "test.h"
int add(int a,int b)
{

return a+b;
}

现在分别进行静动态库编译:

2.1静态库:

g++  -c  test.cpp

以上生成 test.o (-c:只编译不链接,只生成目标文件)

ar -scr libtest.a test.o

生成 libtest.a 静态库

2.2 动态库

利用以上生成的 test.o

g++ -fPIC -shared -o libtest.so test.o

生成动态库 libtest.so

3 cgo 使用静态库

// main.go
package main
/*
CPART
*/ 
import "C"
import "fmt"
func main() {
    a := C.int(3)
    b := C.int(5)
    fmt.Println(C.add(a,b))
}

以上是 main.go的代码,其中CPART 是下面要针对静动态库进行修改的。
对于静态库,有两点需要注意:
1 静态库的寻找目录
2 使用的静态库

CPART 可以改为

#cgo CFLAGS: -I ./temp
#cgo LDFLAGS: -L ./temp -ltest
#include "test.h"

运行命令

cd  example
go run main.go // or go build -o exam && ./exam

对于动态库,依旧需要注意寻找库的路径,可以设置 LD_LIBRARY_PATH 环境变量,或者直接把 libtest.so 放在 /usr/lib, 然后更改 CPART 为:

#cgo CFLAGS: -I ./temp
#cgo LDFLAGS:  -ltest
#include "test.h"

程序执行与以上的方式一样。
如果报错:

 cannot open shared object file: No such file or directory
exit status 127

说明 没有找到动态库文件, 自定义动态库的搜索路径也可以看看 ldconfig 的使用

说明

1 以上的c/c++ 程序只是一个 cpp, 如果有多个的(test.cpp, test.h, exam.cpp, exam.h)该如果使用? 方法类似,可以网上找相关资料了解。
2 如果动态库与静态库文件放在一个目录下,会发生什么情况?
可以参考下:GCC 库路径里同时有相同文件名的动态库和静态库 https://www.cnblogs.com/mydriverc/p/7345873.html
3 gcc 与 g++ 区别
https://blog.csdn.net/na_beginning/article/details/53236968

猜你喜欢

转载自blog.csdn.net/a1368783069/article/details/84238743
今日推荐