编写动态链接库

    技术2022-07-10  125

    很多时候我们写代码的时候会经常用到某些代码段,比方说求两个或几个整数的和或者将一个整形数组转化为二叉树等等。经常使用这些代码,但是每一次又得重新再写一遍,次数多了等于就是重复无用劳动了。所以,可以自己动手写一个自己的动态链接库,保存起来。下次用到只需要加上库就ok了,这样既方便了自己又对动态链接库本身的工作原理理解更深了。

    windows的链接库和linux的链接库在实现原理上大同小异,只是名字有点区别罢了。链接库分两种,动态的和静态的。windows下分别用.lib和.dll来表示,而linux下用.a和.so来表示。静态链接库是指编译代码时即将整个库编到可执行文件中,此时该程序完全拥有库所实现的功能,即运行时不再和库有任何瓜葛。动态链接库则不一样,编译时只是将库中所用到的函数和功能的入口地址编译到可执行文件中,当程序执行到该函数时,程序即跳转到库的函数入口处,因此它们之间是动态的联系在一起的。

    Linux环境下

    linux下动态链接库有一套自己的命名方法,只有正确命名才能够正确的加载和运行。方法为libxxx.so.x,其中xxx表示名字,一般来说就是该so库的作用,后面的x表示版本号,因为so库往往会有版本升级。如:libply.so.4.4.0 而在加载时往往用的是该so库的软链接,如果版本升级了只需要将软链接链到最新的so库就能解决问题,所以这种方法很实用。

    下面编写一个两个整数相加的动态库。

    动态库源码add.cc

    int add(int x, int y) { return x+y; }

    编译

    g++ add.cc -fPIC -shared -o libadd.so

    -fPIC 是指编译的so库不依赖于具体路径。

    生成libadd.so

    测试代码源码test.cc

    #include<iostream> int add(int,int); int main() { int a = 10; int b = 20; int c = add(a,b); std::cout<<"a + b = "<<c<<std::endl; return 0; }

    编译

    g++ test.cc -o test -ladd cd /etc/ld.so.conf.d/ sudo getdit local.conf

    添加:/usr/local/lib 保存后,运行命令

    ldconfig

    表示ld的默认路径发生了变化并将新加的路径添上。

    将libadd.so放到/usr/local/lib中去。

    cd 到 test.cc 目录

    ./test

    输出:

    a+b=30

    Win环境下

    新建VS工程,Win32-Win32项目-名称:WinDll-确定-DLL-完成

    WinDll.cpp

    #include <windows.h> #include "WinDll.h" EXPORT int sum (int a, int b) { return a + b; } #ifndef WINDLL_H #define WINDLL_H #ifdef __cplusplus #define EXPORT extern "C" __declspec (dllexport) #else #define EXPORT __declspec (dllexport) #endif EXPORT int sum (int a, int b); #endif

    编译,Ctrl+Shift+B

    此时Debug文件夹中生成了WinDll.dll

    新建测试工程,TestCode main.cpp

    #include <iostream> #include <main.h> using namespace std; int main() { cout << sum(1, 2) << endl; return 0; }

    VS添加动态库,TODO:)

    参考链接: https://blog.csdn.net/tanga842428/article/details/79666950 https://blog.csdn.net/ecnu_lzj/article/details/73007520

    Processed: 0.019, SQL: 9