windows和Linux 动态库与静态库制作

来源:互联网 发布:linux防火墙开放端口 编辑:程序博客网 时间:2024/05/17 06:31
> 动态库与静态库

Linux:

动态库:     // 1
1.vim lib.c
int foo(int a, int b)
{
     return a+b;
}

2.gcc -fpic -shared lib.c -o libmylib.so     // 动态库编译

3.vim uselib.c
extern int foo(int a, int b);
int main()
{
     printf("result is %d\n", foo(1, 2));
}
4.gcc uselib.c -lmylib -L.     // 在当前目录查找动态库, 连接动态库  

5.export LD_LIBRARY_PATH=.     // 编译时在当前目录查找动态库(这个环境变量只能在当前窗口使用),
或者将动态库拷贝到usr/lib

6../a.out

制作Linux动态库 :     // 2


gcc  -c    itcast_asn1_der.c  -o itcast_asn1_der.o  -fPIC  (生成与位置无关的代码)       ./a.out  运行之后  加载。 延迟载入。

     -c    itcastderlog.c

     -c    keymng_msg.c

ar 制作静态库。   

gcc -shared  -o lib库名.so  itcast_asn1_der.o itcastderlog.o keymng_msg.o  ---->   lib库名.so


2. 动态库使用:

    lib库名.so  文件 本身不能执行。

    gcc test.c -o a.out -L 指定库所在路径 -l 指定库名 (去掉lib, 去掉.so) -I 指定库所对应的头文件所在目录   ---> a.out


    运行 : ./a.out   ----》  报错!  --》  原因:  动态连接器,找不到加载动态库的目录位置。    ldd  a.out    找不到:  ===> not found


     错误提示:./a.out: error while loading shared libraries: libmymessagereal.so: cannot open shared object file: No such file or directory

      -l、-L 给 “连接器” 指定动态库所在位置。

      解决:     1. 将自定义的动态库 cp 放到 标准C库所在目录位置;(不推荐)

                     2. 在可执行文件所在目录位置 执行命令: export LD_LIBRARY_PATH = 库路径;  (临时生效)

                     3. 帮助动态连接器 指定加载 动态库目录位置。 export LD_LIBRARY_PATH = 库路径; 写入 ~/.bash_profile(red hat,Ubuntu下是~./bashrc),  中

ldd a.out 成功显示动态库位置。    ./a.out 运行。



静态库:

1) gcc -c lib.c lib.o     //首先需要将.c文件编译为.o文件
2) ar rcs libmylib.a lib.o
3) gcc uselib.c -o a.out -lmylib -L.

1) 有同名的动态库与静态库时,优先选择动态库,如果要使用静态库加上 -static

2) 通过以下方式可以指定某些库使用静态链接,而某些库使用动态链接
-Wl,-Bstatic -ltest -Wl,-Bdynamic -ltest2

windows动态库 :

动态库创建:

    动态库基本常识:

    1.     win环境下,动态库―― xxx.dll  xxx.lib  xxx.h

        Linux环境下,动态库―― xxx.so    xxx.h  -L  -l 动态链接器 LD_LIBRARY_PATH    ldd keymngserver  ====> not found

    2.     动态库不是一个exe。是系列函数的集合(二进制)。   keyMsg_Encode.c

        按某种规范制作,被操作系统加载。  VS -- ldd

        如: 111.exe  --- aaa.dll   

            系统在加载111.exe时,检查111.exe运行是否需要额外的动态库。

            若需要,则按一定规则加载。找到成功加载,找不到。报错。----指定动态库路径

动态库的制作:

    动态库的命名,不要使用中文。

    创建时选择.dll生成项目。  但,不能运行。


    动态库API函数的导出。 

        只将用户使用的指定某几个函数从动态库中导出。

        使用 __declspec(dllexport) 宏,提示编译器。在编译程序的时候,需特殊处理的函数。

        注意: .c 文件 和 .h 文件 均需要添加该宏!! (VS2013 要求)

    默认生成的动态库位于上层目录下的 Debug 目录内。



动态库制作结果:

    xxxxx.dll    二进制目标函数集,可被操作系统加载

    xxxxx.lib    是对dll的描述文件 (包含多少函数,哪些被导出。。。。)

    .h 以及以上2个文件 即可为exe执行提供支持。 但提供给用户时, .h中的 __declspec(dllexport) 宏应删除。



动态库调用和调试:

    通知VS2013编译器,使用提供的动态库。

        将.dll .lib .h三个文件放置在 .c同级目录下。

        右键项目“属性”---“配置属性”---“链接器”---“输入”--- “附加依赖项”---下拉菜单“编辑”

        ----输入【描述dll信息lib文件  xxxxx.lib】       

    常见错误:

        1. 若xxx.lib配置错误,则VS编译器无法找到所用函数。

        2. 如若在运行111.exe时,说明操作系统找不到动态库加载路径。

            1. 配置PATH  2. 将exe和动态库dll置于同一目录下即可。
  1.         如果运行时出错可以把dll文件放到上一级目录的debug的目录下

动态库内存释放:

    遵循一个原则:谁分配,谁释放。

              调用动态库函数分配的内存,也一定要调用动态库函数来释放内存。











































0 0