linux下.o .a .so文件解析

linux下文件的类型是不依赖于其后缀名的,但一般来讲:
.o,是目标文件,相当于windows中的.obj文件
.so 为共享库,是shared object,用于动态连接的,和dll差不多
.a为静态库,是好多个.o合在一起,用于静态连接

.la为libtool自动生成的一些共享库,vi编辑查看,主要记录了一些配置信息

1:创建.a库文件和.a库文件的使用

//first.h

#ifndef _FIRST_H_
#define _FIRST_H_
int first();
int second();
#endif

//First.c

#include <stdio.h>
#include "first.h"
int first()
{
    printf("First Hello World!\n");
    return 0;
}

//second.c

#include <stdio.h>
#include "first.h"
int second()
{
    printf("second printf\n");
    return 0;
}

gcc -c First.c second.c first.h

生成:First.o second.o

ar -r libt.a First.o second.o

要想查看libt.a中 有哪些文件可以用命令

ar -t libt.a

显示:First.o

            second.o

使用libt.a库

gcc -o test test.c libt.a

执行./test

显示:

just a test
First Hello World!
second printf

2:.so库的创建和使用

//so_test.h:
#ifndef _SO_TEST_H_
#define _SO_TEST_H_
void so_testa();
void so_testb();
void so_testc();
#endif

//so_testa.c:
#include "so_test.h"
void so_testa()
{
    printf("this is in so_testa....\n");
}

//test_b.c:
#include "so_test.h"
void so_testb()
{
    printf("this is in so_testb...\n");
}

//test_c.c:
#include "so_test.h"
void so_testc()
{
    printf("this is in so_testc....\n");
}

将这几个文件编译成一个动态库:libtest.so
gcc so_testa.c so_testb.c so_testc.c -fPIC -shared -o libtest.so

动态库的链接
我们已经成功生成了一个自己的动态链接库libtest.so,下面我们通过一个程序来调用这个库里的函数

程序的源文件为:testso.c

//testso.c:
#include "so_test.h"
int main()
{
    so_testa();
    so_testb();
    so_testc();
    return 0;
}

将testso.c与动态库libtest.so链接生成执行文件testso:
$ gcc testso.c -L. -ltest -o testso
l 测试是否动态连接,如果列出libtest.so,那么应该是连接正常了
$ ldd testso

 linux-gate.so.1 =>  (0x00d8e000)
        libtest.so => /home/liping/Desktop/testa/testso/libtest.so (0x009a9000)
        libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x0022b000)
        /lib/ld-linux.so.2 (0x00577000)
 执行./testso,可以看到它是如何调用动态库中的函数的

this is in so_testa....
this is in so_testb...
this is in so_testc....

编译参数解析
最主要的是GCC命令行的一个选项:
-shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
 -L.:表示要连接的库在当前目录中(注意这个大写的L后面有个小点点 ,没有是不对的)
 -ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称
 LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。

当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用 /sbin/ldconfig来达到同样的目的。不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。

不过关于设置环境变量 LD_LIBRARY_PATH的方式没有尝试,也不知道是否可行,因为不知道这种方式如何入手

因为我有root的权限,就直接修改/etc/ld.so.conf文件,把当前的libtest.so路径/home/liping/Desktop/testa/testso添加到ld.so.conf中,然后进入/sbin/路径下执行ldconfig这样就可以正常的连接了!测试成功后,很开心!在这里分享一下!转载的地址如下:

http://www.jcwcn.com/forum.php?mod=viewthread&tid=339990

参考的地址还有一些,这里就不一一列举了!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值