制作静态、动态链接库

一前言.
在windows下,静态链接库文件后缀是.lib, 动态链接库文件后缀是.dll
在linux下,静态链接库文件后缀是.a, 动态链接库文件后缀是.so

二.linux下的静态链接库(暂不说windows下的dll)
1.新建一个printf.c 和 printf.h文件,在printf.c文件写上相应的测试函数,以及在.h文件中声明。
2.新建一个makefile文件,在makefile中写:

                all:
                    gcc printf.c -o printf.o -c
                    ar -rc libprintf.a printf.o

                clean:
                    rm -rf *.o *.a
            备注:-o参数用于指定输出(out)文件名。不用-o的话,一般会在当前文件夹下生成默认的a.out文件作为可执行程序。
                                 -c参数表示只编译(compile)源文件但不链接,会把.c或.cc的c源程序编译成目标文件。咱们这里是生成库文件,所以也不需要链接。
                                 使用ar工具进行打包成.a归档文件, -r将文件插入备存文件中, -c建立备存文件。
                                 这里注意 库名不能随便乱起,一般是lib+库名称,后缀名是.a表示是一个归档文件,制作出来了静态库之后,发布时需要发布.a文件和.h文件。

                至此静态链接库就制作完成。那如何引用它呢?

                    1.我们将上面制作好的libprintf.a文件和printf.h复制到一个新的test文件夹中。再新建一个test.c文件和一个makefile文件。
                            注意:test.c中头文件应包含printf.h------>#include "printf.h" //(注意双引号)

                            然后写好main函数,在main函数中调用printf.c中写好的测试函数。

                        2.接下来就是写makefile
                                `
                                    all:
                                        gcc test.c -lprintf -L.
                                        #注意-L后面的.

                                    clean:
                                        rm -rf *.o *.out
                                    `
                                    -l参数就是用来指定程序要链接的库,-l参数紧接着就是库名,那么库名跟真正的库文件名有什么关系呢?就拿数学库来说,他的库名是m,他的库文件名是libm.so,很容易看出,把库文件名的头lib和尾.so去掉就是库名了。
                                    -L .,表示将当前目录作为第一个寻找库文件的目录, 寻找的顺序是:./–>/lib–>/usr/lib–>/usr/local/lib

                                    注意:编译时,必须得告诉编译器静态链接库的名字和路径(没告诉的话会去默认路径下查找),这点也很容易理解。
                        3.编译后 执行a.out文件,即输出printf.c中测试函数的内容,整个下来就是静态链接库的制作和使用。

三.linux下的动态链接库
1.同样新建一个printf.c printf.h 和makefile
2.makefile中编写如下:
gcc printf.c -o printf.o -c -fPIC<br/>gcc -o libprintf.so printf.o -shared <br/>
-fPIC参数是位置无关码,-shared参数是按照共享库的方式来链接。

                    此时生成的libprintf.so文件即动态链接库文件,那么在发布的时候,发布libprintf.so和printf.h文件即可

                3.同样新建一个test文件,将libprintf.so与printf.h文件复制进去,新建一个test.c与makefile文件。
                4.makefile写法与静态链接库一致
                                                            `
                                    all:
                                        gcc test.c -lprintf -L.
                                        #注意-L后面的.

                                    clean:
                                        rm -rf *.o *.out
                                    `
                        但是由于静态链接与动态链接实现的机制不同,具体哪些不同,请自行百度搜索,很多。
                        这里直接去执行./a.out是执行不成功的
                        报错误:
                            error while loading shared libraries: libprintf.so: cannot open shared object file: No such file or directory

                        原因是使用动态链接库时,需要临时加载动态链接库,而不是在编译时将库里面的内容加载出来,编译到一起。这是与静态链接库不同的地方。所以,它这里找不到库文件在哪里,那么有一下几种解决办法:
                        (1)将libprintf.so放到固定目录下就可以了,这个固定目录一般是/usr/lib目录。 cp libprintf.so /usr/lib即可
                        (2)使用环境变量LD_LIBRARY_PATH。操作系统在加载固定目录/usr/lib之前,会先去LD_LIBRARY_PATH这个环境变量所指定的目录下去寻找,如果找到就不用去/usr/lib下面找了,如果没找到再去/usr/lib下面找。所以解决方案就是将libprintf.so所在的目录导出到环境变量LD_LIBRARY_PATH中即可。

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH: + 文件所在的路径。
5.再去执行a.out即可执行成功。

四.总结
1.咱们注意到静态链接库与动态链接库中 test文件夹中makefile,都有一句gcc test.c -lprintf -L,注意这个-lprintf参数,假如在文件夹中,又有静态链接库,又有动态链接库,那编译器该如何选择呢? 答案是会优先选择动态链接库文件。
2.还有个nm命令也很有用,它可以用来查看一个.a或者.so文件中都有哪些符号,简单来说就是看有哪些函数。
3.ldd命令(动态链接库):作用是可以在一个使用了共享库的程序执行之前解析出这个程序使用了哪些共享库,并且查看这些共享库是否能被找到,能被解析(决定这个程序是否能正确执行)。

原文地址:http://blog.51cto.com/13403824/2161668

时间: 2024-10-03 08:29:48

制作静态、动态链接库的相关文章

Linux库函数制作(静态库、动态库)

Linux库函数制作(静态库.动态库) 静态库与动态库 链接方式 链接分为两种:静态链接.动态链接 静态链接: 由链接器在链接时将库的内容加入到可执行程序中 静态链接的特点是: 优点: 对运行环境的依赖性较小,具有较好的兼容性 缺点: 生成的程序比较大,需要更多的系统资源,在装入内存时会消耗更多的时间 库函数有了更新,必须重新编译应用程序 动态链接: 连接器在链接时仅仅建立与所需库函数的之间的链接关系,在程序运行时才将所需资源调入可执行程序 动态链接的特点: 优点: 在需要的时候才会调入对应的资

&nbsp; &nbsp; &nbsp; &nbsp; 自己制作静态链接库并使用

目的隐藏源代码只提供给.a 与.h文件 /*aston.c */#include <stdio.h>void func1( void ){ printf("func1 in aston.c\n");}int  func2(int a,int b){ printf("func2 in aston.c\n"); return a+b;}//aston.hvoid func1( void ); int  func2(int a,int b); //Makefi

利用CSS制作静态网页的注意事项

利用CSS制作静态网页主要是在<head>里面使用外联CSS文件来赋予网页样式 首先用div分区块,了解网页布局,脑子里面有个大概的页面布局 目前学习写的几种的网页布局可以分为以下几种情况: 1.页面中间 centen ,两边留白 :直接测量 centen 内容的宽度和高度,利用 maigin:auto 让内容居中即可: 2.页面顶部 head 满页面内容 ,下面centen 居中 ,两边留白:head 宽度设为100%,中间centen 内容的宽度和高度,利用 maigin:auto 让内容

iOS制作静态包duplicate symbol解决办法

原文链接 http://stackoverflow.com/questions/41217839/duplicate-symbols-when-integrating-firebase-and-google-sign-in-sdks-manually-wit 制作静态包时我们很可能会引入第三方的库,这种时候很容易出现我们的静态包和主工程引入的第三方库有相同库的情况,为了解决这个问题上面链接给出了解决方案. 1.先制作一个静态包. 2.使用 lipo -info 查看这个静态包是不是fat fil

用ps切片快速制作静态网页

利用ps快速的制作静态网页 步骤: 1.在ps中打开一个网页模板,利用切片工具进行剪裁 2存储方式是:存储为web所用格式 3设置存储像素1366.GIF格式 4保存到文件夹中以html+图像 的格式 5打开html,打开方式为DW方式打开 6:根据网页在进行对其修改

制作静态库文件(.a文件)

1.创建静态库工程: 在Xcode中new一个新的project,选择IOS下面的Framework&Library,下面有一个Cocoa Touch Static Library.直接next去建立一个静态库工程.(如下图) 2.编写工程: 现在就可以编写静态库要实现的功能(新建文件,编写代码) 3.配置静态库工程对应的Copy Files和Copy Headers: 在工程设置的Build Phases中设置(如下图),选择右下角的Add Build Phases,添加Copy Files和

python2-gst0.10制作静态包的补丁 v1.1

gst制作成了静态库,而python2的gst有多个动态库引用gst的库 因此,想了一个办法将python2所需要的gst打包成一个单独的共享库 办法就是,将python2_gst所有的.so先制作成.a 通过nm -g加过滤的办法得到所有链接的gst函数 将这些函数生成一个小文件,在一个静态函数中引用所有这些函数 然后,将这个小文件编译成so文件,并链接gst库,这样,python2_gst所需要的gst函数就全部链接进来了 同时,可以将gst动态插件的方式也在启动时就注册进来,那样,pyth

python2-gst0.10制作静态包的补丁

gst制作成了静态库,而python2的gst有多个动态库引用gst的库 因此,想了一个办法将python2所需要的gst打包成一个单独的共享库 办法就是,将python2_gst所有的.so先制作成.a 通过nm -g加过滤的办法得到所有链接的gst函数 将这些函数生成一个小文件,在一个静态函数中引用所有这些函数 然后,将这个小文件编译成so文件,并链接gst库,这样,python2_gst所需要的gst函数就全部链接进来了 同时,可以将gst动态插件的方式也在启动时就注册进来,那样,pyth

在Windows下制作静态库和动态库

一:静态库的创建 VC++6.0中new一个的为win32 static library工程,之后有二个选项.根据需求选吧. 具体的类或者函数的添加过程和标准的工程一样,直接创建新的类或者添加新 的.h(例:MY.h)和.CPP(例:MY.cpp)文件.然后在其中编写实现. 完成后编译会生成一个.lib文件(例如:生成的是MY.lib)我生成的文件为TEST.lib