在软件开发过程中,代码的复用是非常重要的一环。为了避免代码重复编写,程序员们采用了多种方法,其中之一就是链接库。通过链接库,程序员可以将一些经常使用的代码封装成库,以后再需要使用时直接调用即可,大大提高了代码的复用性和可维护性。此外,链接库还可以通过减小可执行文件的大小来提高程序的运行效率。本文将详细介绍如何在Linux系统上编译动态链接库,并介绍一种通过链接其他库实现更灵活和高效的编程方式。
一、动态链接库编译
在Linux系统中,链接库可以分为静态链接库和动态链接库两种。静态链接库是指在编译时将链接库的代码编译到可执行文件中,而动态链接库则是在程序运行时才进行链接。动态链接库可以分为两种类型:共享对象(shared object)和动态装入模块(dynamic loaded module)。其享对象是一种可重定向的文件,可以被多个程序共享,并且可以在多个程序间动态加载和卸载。动态装入模块则是一种可以在程序运行时动态加载和卸载的代码模块。在Linux系统中,动态链接库使用的是共享对象。接下来我们将讲解如何在Linux系统中编译动态链接库。
1. 编写源文件
动态链接库编译的之一步是编写源文件。在编写源文件时,需要将要封装成库的代码封装到一个函数中,并在函数上方加上__attribute__((visibility(“default”))),以便外部程序访问。代码如下:
“`
#include
__attribute__((visibility(“default”))) void hello_world(void)
{
printf(“hello world!\n”);
}
“`
2. 编译源文件
编写完源文件后,需要使用gcc编译源文件,生成共享对象文件。gcc命令如下:
“`
$ gcc -fPIC -shared hello_world.c -o libhello.so
“`
其中,-fPIC表示生成位置独立的代码,-shared表示生成共享对象文件,-o表示输出文件名。编译完成后,在当前目录下会生成一个名为libhello.so的共享对象文件。
3. 使用动态链接库
编译完成后,可以使用ldd命令查看编译生成的共享对象文件的动态链接库依赖关系。
“`
$ ldd libhello.so
linux-vdso.so.1 => (0x00007ffda7ffa000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f05c6b9f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f05c6f66000)
“`
使用动态链接库的方式有两种:
之一种是在程序编译时指定要使用的共享对象文件。使用的gcc命令如下:
“`
$ gcc example.c -L. -lhello -o example
“`
其中,-L指定库的搜索路径,.表示当前目录,-lhello表示使用名为libhello.so的共享对象文件。编译完成后,可以使用ldd命令查看编译生成的可执行文件的动态链接库依赖关系。
“`
$ ldd example
linux-vdso.so.1 => (0x00007ffd25d88000)
libhello.so => /home/example/libhello.so (0x00007f938d26f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f938ceae000)
/lib64/ld-linux-x86-64.so.2 (0x00007f938d472023)
“`
第二种是在程序运行时动态加载共享对象文件。使用的系统调用是dlopen()。代码如下:
“`
#include
#include
#include
int mn(int argc, char **argv)
{
void *handle;
void (*hello_world)(void);
char *error;
handle = dlopen(“./libhello.so”, RTLD_LAZY);
if (!handle) {
fprintf(stderr, “%s\n”, dlerror());
exit(EXIT_FLURE);
}
dlerror();
hello_world = dlsym(handle, “hello_world”);
if ((error = dlerror()) != NULL) {
fprintf(stderr, “%s\n”, error);
exit(EXIT_FLURE);
}
(*hello_world)();
dlclose(handle);
exit(EXIT_SUCCESS);
}
“`
对于第二种方式,需要在编译时加上-l dl参数,表示链接动态链接库处理函数库。gcc命令如下:
“`
$ gcc example.c -o example -ldl
“`
4. 动态链接库使用场景
动态链接库一般用于一些经常使用的代码的封装,例如网络通信、文件操作、数据解析等。在程序运行时,只需要加载相应的共享对象文件就可以使用其中的函数,而不需要重新编写代码。此外,动态链接库还可以减小可执行文件的大小,提高程序的运行效率。
二、链接其他库的编程方式
除了编写自己的链接库,还可以使用其他开发者编写的链接库,以便更加灵活和高效地开发程序。例如,可以使用OpenCV库进行图像处理,使用OpenGL库进行图形渲染等。
链接其他库的方法如下:
1. 安装库文件
首先需要安装要使用的库文件。例如,安装OpenCV库文件:
“`
$ sudo apt install libopencv-*dev
“`
安装OpenGL库文件:
“`
$ sudo apt install freeglut3-dev
“`
2. 编写源文件
编写源文件时需要包含要使用的库的头文件,并在编译时链接库文件。例如使用OpenCV库进行图像处理:
“`
#include
#include
int mn()
{
cv::Mat src = cv::imread(“test.png”);
cv::Mat dst;
cv::cvtColor(src, dst, cv::COLOR_RGB2GRAY);
cv::imwrite(“test_gray.png”, dst);
std::cout
return 0;
}
“`
在编译时需要链接OpenCV库文件:
“`
$ g++ example.cpp -o example `pkg-config opencv –cflags –libs`
“`
3. 使用其他库的好处
使用其他库可以大大降低程序员的工作量,同时还可以提高程序的稳定性和效率。例如使用OpenCV库进行图像处理,可以避免自己对图像处理算法的编写,减少程序出错的可能性,同时还可以提升程序的运行效率和图像处理的质量。
相关问题拓展阅读:
- 如何使用lame源代码在编译生成linux环境下的动态库
如何使用lame源代码在编译生成linux环境下的动态库
动态库的生成
1>首先生成目标文件,但是此时要加编译器选项-fpic和链接器选项-shared,
gcc -fpic -c add.c
gcc -fpic -c sub.c
生成中间文件add.o和sub.o
2>其次生成动态库
gcc -shared –o libtiger.so add.o sub.o
生成动态库libtiger.so,libtiger.so就是我们生成的目标动态库。我们以后使用动态库和main.c程序生成可执行程序
说明:
以上两部也可以合成一步搞定:
gcc -fpic -shared add.c sub.c -o libtiger.so
2.使用动态链接库
在编译程序时,使用动态链接库和静态库是一致的,使用”-l库名”的方式,在生成可执行文件的时候会链接库文件。
1>使用命令:
gcc -o main main.c -L ./ -ltiger
2>-L指定动态链接库的路劲,-ldtiger链接库函数tiger。-ltiger是动态库的调用规则。Linux系统下的动态库命名方式是lib*.so,而在链接时表示位-l*,*是自己命名的库名。
3>但是程序会提示如下错误
error while loading shared libraries: libtiger.so: cannot open shared object file: No such file or direct
这是因为程序运行时没有找到动态链接库造成的。程序编译时链接动态库和运行时使用动态链接库的概念是不同的,在运行时,程序链接的动态链接库需要在系统目录下才行。
4>使用以下方法可以解决此问题
a. 在linux下最方便的解决方案是拷贝libtiger.so到绝对目录 /lib 下(但是,要是超级用户才可以,因此要使用sudo哦,亲)。就可以生成可执行程序了
b.第二种方法是:将动态链接库的目录放到程序搜索路径中,可以将库的路径加到环境变量LD_LIBRARY_PATH中实现:
export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
linux编译动态的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于linux编译动态,链接库的方法如何编译动态链接库并在Linux上使用,一种通过链接其他库实现更灵活和高效的编程方式。,如何使用lame源代码在编译生成linux环境下的动态库的信息别忘了在本站进行查找喔。
香港服务器首选树叶云,2H2G首月10元开通。
树叶云(www.IDC.Net)提供简单好用,价格厚道的香港/美国云服务器和独立服务器。IDC+ISP+ICP资质。ARIN和APNIC会员。成熟技术团队15年行业经验。
文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/161224.html<