ToB企服应用市场:ToB评测及商务社交产业平台

标题: 【万能皆可链接】C++中的动态链接库编译与加载库函数,Cython编译后的.so使 [打印本页]

作者: 嚴華    时间: 2022-6-24 08:41
标题: 【万能皆可链接】C++中的动态链接库编译与加载库函数,Cython编译后的.so使
什么是库

库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,
本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:静态库(.a、.lib)和动态库(.so、.dll)。 windows上对应的是.lib .dll linux上对应的是.a .so


 
静态库

在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。
静态库与汇编生成的目标文件一起链接为可执行文件,那么静态库必定跟.o文件格式相似。其实一个静态库可以简单看成是一组目标文件(.o/.obj文件)的集合


Linux静态库命名规范,必须是"lib[your_library_name].a":lib为前缀,中间是静态库名,扩展名为.a。
创建静态库(.a)
通过上面的流程可以知道,Linux创建静态库过程如下:

        g++ -c main_c.cpp
注意带参数-c,否则直接编译为可执行文件

        ar -crv libmain_c.a main_c.o
生成静态库libmain_c.a


动态库


另一个问题是静态库对程序的更新、部署和发布页会带来麻烦。如果静态库liba.lib更新了,所以使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,可能是一个很小的改动,却导致整个程序重新下载,全量更新)。
动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。动态库在程序运行是才被载入,也解决了静态库对程序的更新、部署和发布页会带来麻烦。用户只需要更新动态库即可,增量更新


动态库特点

C++中创建动态库

如果是cpp还要加上extern "C",因此C编译器编译后在符号库中的名字为_foo,而C++编译器为了实现重载则会产生像_foo_int_int之类的名称,因此如果使用g++或者cpp编译动态链接库,则会找不到对应函数出现Segmentation fault
同时要注意编译器的选择,虽然都不会报错,但是执行逻辑不一样




编写gen.c
  1. int gen(){
  2.     return 1;
  3. }
复制代码
编译.c为.so文件
  1. gcc  gen.c -o gen.so -g -Wall -fPIC -shared
复制代码
编写test_main.cpp文件
[code]#include #include typedef int (*PYMAIN)();using namespace std;int main() {  PYMAIN py_main = NULL;  void* handle = dlopen("./gen.so", RTLD_LAZY);  if (!handle) {    std::cout




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4