/*  
Linux下动态链接库的创建和使用_g++    SList.h  
Linux下动态链接库的创建和使用_g++    单链表的实现
Linux下动态链接库的创建和使用_c++_03
*/

Linux下动态链接库的创建和使用_c++_04
Linux下动态链接库的创建和使用_c++_04#ifndef SLIST_H_
Linux下动态链接库的创建和使用_c++_04
#define SLIST_H_
Linux下动态链接库的创建和使用_c++_04#include 
<iostream>
Linux下动态链接库的创建和使用_c++_04
Linux下动态链接库的创建和使用_c++_04
class Node
Linux下动态链接库的创建和使用_#include_10Linux下动态链接库的创建和使用_共享库_11
...{
Linux下动态链接库的创建和使用_g++
public:
Linux下动态链接库的创建和使用_g++    
int info;
Linux下动态链接库的创建和使用_g++    Node 
*next;
Linux下动态链接库的创建和使用_g++    Node(
int el,Node* ptr=0)
Linux下动态链接库的创建和使用_#include_16Linux下动态链接库的创建和使用_#include_17    
...{
Linux下动态链接库的创建和使用_g++        info 
= el;
Linux下动态链接库的创建和使用_g++        next 
= ptr;
Linux下动态链接库的创建和使用_#include_20    }

Linux下动态链接库的创建和使用_c++_03}
;
Linux下动态链接库的创建和使用_c++_04
Linux下动态链接库的创建和使用_#include_10Linux下动态链接库的创建和使用_共享库_11
class SList...{
Linux下动态链接库的创建和使用_g++
public:
Linux下动态链接库的创建和使用_#include_16Linux下动态链接库的创建和使用_#include_17    SList()
...{
Linux下动态链接库的创建和使用_g++        head 
= tail = 0;
Linux下动态链接库的创建和使用_#include_20    }

Linux下动态链接库的创建和使用_#include_16Linux下动态链接库的创建和使用_#include_17    
int isEmpty()...{
Linux下动态链接库的创建和使用_g++        
return head == 0;
Linux下动态链接库的创建和使用_#include_20    }

Linux下动态链接库的创建和使用_g++    
void addToHead(int);
Linux下动态链接库的创建和使用_g++    
int deleteFromHead();
Linux下动态链接库的创建和使用_g++    friend std::ostream
& operator<<(std::ostream&const SList&);
Linux下动态链接库的创建和使用_g++    
virtual ~SList();
Linux下动态链接库的创建和使用_g++
private:
Linux下动态链接库的创建和使用_g++    Node 
*head,*tail;
Linux下动态链接库的创建和使用_c++_03}
;
Linux下动态链接库的创建和使用_c++_04
Linux下动态链接库的创建和使用_c++_04
#endif  //SLIST_H_
Linux下动态链接库的创建和使用_c++_04
Linux下动态链接库的创建和使用_#include_10Linux下动态链接库的创建和使用_共享库_11
/**//*  SList.cpp  */
Linux下动态链接库的创建和使用_c++_04
Linux下动态链接库的创建和使用_c++_04#include 
"SList.h"
Linux下动态链接库的创建和使用_c++_04
Linux下动态链接库的创建和使用_#include_10Linux下动态链接库的创建和使用_共享库_11SList::
~SList()...{
Linux下动态链接库的创建和使用_#include_16Linux下动态链接库的创建和使用_#include_17    
for(Node* p;!isEmpty();)...{
Linux下动态链接库的创建和使用_g++        p 
= head->next;
Linux下动态链接库的创建和使用_g++        delete p;
Linux下动态链接库的创建和使用_g++        head 
= p;
Linux下动态链接库的创建和使用_#include_20    }

Linux下动态链接库的创建和使用_c++_03}

Linux下动态链接库的创建和使用_c++_04
Linux下动态链接库的创建和使用_#include_10Linux下动态链接库的创建和使用_共享库_11
void SList::addToHead(int el)...{
Linux下动态链接库的创建和使用_g++    head 
= new Node(el,head);
Linux下动态链接库的创建和使用_g++    
if(tail == 0)
Linux下动态链接库的创建和使用_g++        tail 
= head;
Linux下动态链接库的创建和使用_c++_03}

Linux下动态链接库的创建和使用_c++_04
Linux下动态链接库的创建和使用_#include_10Linux下动态链接库的创建和使用_共享库_11
int SList::deleteFromHead()...{
Linux下动态链接库的创建和使用_g++    
int el = head->info;
Linux下动态链接库的创建和使用_g++    Node 
*tmp = head;
Linux下动态链接库的创建和使用_g++    
if(head == tail)
Linux下动态链接库的创建和使用_g++        head 
= tail = 0;
Linux下动态链接库的创建和使用_g++    
else head = head->next;
Linux下动态链接库的创建和使用_g++    delete tmp;
Linux下动态链接库的创建和使用_g++    
return el;
Linux下动态链接库的创建和使用_c++_03}

Linux下动态链接库的创建和使用_c++_04
Linux下动态链接库的创建和使用_#include_10Linux下动态链接库的创建和使用_共享库_11std::ostream
& operator<<(std::ostream& os, const SList& ss)...{
Linux下动态链接库的创建和使用_g++    Node
* p;
Linux下动态链接库的创建和使用_g++    p
=ss.head;
Linux下动态链接库的创建和使用_g++    os
<<p->info;
Linux下动态链接库的创建和使用_共享库_82 ign="top" />    
for(p=p->next;p;p=p->next)
Linux下动态链接库的创建和使用_g++        os
<<"->"<<p->info;
Linux下动态链接库的创建和使用_g++    
return os;
Linux下动态链接库的创建和使用_c++_03}

Linux下动态链接库的创建和使用_c++_04
Linux下动态链接库的创建和使用_c++_04
Linux下动态链接库的创建和使用_#include_10Linux下动态链接库的创建和使用_共享库_11
/**//*  main.cpp  */
Linux下动态链接库的创建和使用_c++_04
Linux下动态链接库的创建和使用_c++_04#include 
<iostream>
Linux下动态链接库的创建和使用_c++_04#include 
"SList.h"
Linux下动态链接库的创建和使用_c++_04
Linux下动态链接库的创建和使用_c++_04
using namespace std;
Linux下动态链接库的创建和使用_c++_04
int main(int argc, char* argv[])
Linux下动态链接库的创建和使用_#include_10Linux下动态链接库的创建和使用_共享库_11
...{    
Linux下动态链接库的创建和使用_g++    
Linux下动态链接库的创建和使用_#include_16Linux下动态链接库的创建和使用_#include_17  
int ss[]=...{20,11,21,23,10,19,17,4};
Linux下动态链接库的创建和使用_g++    size_t n 
= sizeof(ss)/sizeof(int);
Linux下动态链接库的创建和使用_g++    SList sl;
Linux下动态链接库的创建和使用_g++    
for(int i=0;i<n;++i)
Linux下动态链接库的创建和使用_g++        sl.addToHead(ss[i]);
Linux下动态链接库的创建和使用_g++    cout
<<sl<<endl;
Linux下动态链接库的创建和使用_g++    
return 0;
Linux下动态链接库的创建和使用_c++_03}

一、创建共享库
1 单独编译SList.cpp,编译时需要传入-fPIC选项,告诉编译器生成位置无关代码.
位置无关代码可以被加载到地址空间的任意位置而不需要修改.

[root@LEE src]# ls
main.cpp  SList.cpp  SList.h
[root@LEE src]# g++ -fPIC -g -c SList.cpp

2 当链接到库时,为链接器传入-shared选项,把目标文件SList.o链接为共享对象
libSList.so.1.0.1
每个共享库都有一个特定的搜索名(soname).搜索名约定如下:
lib+库名+.so+.版本号
在文件系统中,搜索名是一个指向实名的符号连接.每个共享库也有一个特定的实名,约定如下:
搜索名+.子版本号+.发布号
你可以使用一个特殊的编译器选项-Wl,option,将option传给ld,用逗号分隔多个option,
为了在所有的系统上得到最好结果,链接libSList到标准C++库上

[root@LEE src]# g++ -g -shared -Wl,-soname,libSList.so.1 -o libSList.so.1.0.1 SList.o -lstdc++
[root@LEE src]# ls
libSList.so.1.0.1  main.cpp  SList.cpp  SList.h  SList.o

libSList.so.1是搜索名,libSList.so.1.0.1是实名,SList.o是目标文件(也可以是多个目标文件的列表)
 ,-lstdc++是库需要访问的库(也可以是库的列表-llibrary,关于此选项参考附录.)

3 创建一个从soname链接到库
[root@LEE src]# ln -fs libSList.so.1.0.1 libSList.so.1
[root@LEE src]# ln -fs libSList.so.1 libSList.so
 
4  使用-L使链接器在当前目录中查找库,并且使用-lSList告诉它要链接哪个库
[root@LEE src]# g++ -g -c main.cpp -o main.o
[root@LEE src]# g++ -g -o main main.o -L. -lSList
[root@LEE src]# ls
libSList.so    libSList.so.1.0.1  main.cpp  SList.cpp  SList.o
libSList.so.1  main               main.o    SList.h

5 运行命令
[root@LEE src]# LD_LIBRARY_PATH=$(pwd) ./main
4->17->19->10->23->21->11->20

LD_LIBRARY_PATH
  提供用来搜索库的目录路径,以冒号作为间隔.正常情况下它不应该被设置,因为系统文件
/ect/ld.so.conf提供了默认的路径.

二、使用链接库
 当运行一个程序时,动态装载器通常在/ect/ld.so.conf.d目录查找程序所需要的库.但是,如果
LD_LIBRARY_PATH 环境变量被设置,它首先扫描在LD_LIBRARY_PATH 中列出的目录.对于上一节5,如果直接运行
命令 ./main,会出现找不到库的现象.如:
[root@LEE src]# ./main
./main: error while loading shared libraries: libSList.so.1: cannot open shared object file: No such file or directory

上述问题的解决方案有两种(我能想到的):
1 如果LD_LIBRARY_PATH 没设定:
拷贝libSList.so到目录 /usr/local/lib (同理也可以拷到/usr/lib下)
[root@LEE src]# cp libSList.so /usr/local/lib
[root@LEE src]# ldconfig /usr/local/lib
[root@LEE src]# ./main
4->17->19->10->23->21->11->20

2 如果LD_LIBRARY_PATH 设定:
  编辑.bash_profile文件
  添加LD_LIBRARY_PATH:=$LD_LIBRARY_PATH:/path/to/libSList.so(不包括 libSList.so)
  执行.bash_profile 文件.
[root@LEE src]# . /root/.bash_profile
[root@LEE src]# ./main
4->17->19->10->23->21->11->20

 

  这些天看了一些关于静态/动态链接库的贴子和书,将这几天的研究整理成文,决定发表一下.我很早就注册了CSDN,也很想成为一名软件工程师,这个愿望在不久前实现了,所以更加努力,登陆CSDN的次数也有了数量级的增加.我有过一些Linux下的C++程序开发经历,相对于同专业(数学类)的同学,我有着较好的Linux和C++技能.最近在CSDN上看了很多优秀的文章,从中受益良多.这是我第一次发表文章,希望各位多多指教.