.so放哪里 linux
2010-03-31 09:43:00 miaojian_430 阅读数 218

还没填写内容  改天找到合适的再添吧

linux so
2017-04-05 15:03:28 u010359663 阅读数 8
http://mypyg.iteye.com/blog/845915

牵扯到ELF格式,gcc编译选项待补,简单实用的说明一下,对Linux下的so文件有个实际性的认识。
1.so文件是什么?
2.怎么生成以及使用一个so动态库文件?
3.地址空间,以及线程安全.
4.库的初始化,解析:
5.使用我们自己库里的函数替换系统函数:
//-------------------------------------------------------------------------------
1.so文件是什么?
也是ELF格式文件,共享库(动态库),类似于DLL。节约资源,加快速度,代码升级简化。
知道这么多就够了,实用主义。等有了印象再研究原理。
2.怎么生成以及使用一个so动态库文件?
先写一个C文件:s.c
C代码 收藏代码
#include <stdio.h>
int count;
void out_msg(const char *m)
{//2秒钟输出1次信息,并计数
for(;;) {printf("%s %d\n", m, ++count); sleep(2);}
}

编译:得到输出文件libs.o
gcc -fPIC -g -c s.c -o libs.o

链接:得到输出文件libs.so
gcc -g -shared -Wl,-soname,libs.so -o libs.so libs.o -lc

一个头文件:s.h
C代码 收藏代码
#ifndef _MY_SO_HEADER_
#define _MY_SO_HEADER_
void out_msg(const char *m);
#endif

再来一个C文件来引用这个库中的函数:ts.c
C代码 收藏代码
#include <stdio.h>
#include "s.h"
int main(int argc, char** argv)
{
printf("TS Main\n");
out_msg("TS ");
sleep(5); //这句话可以注释掉,在第4节的时候打开就可以。
printf("TS Quit\n");
}

编译链接这个文件:得到输出文件ts
gcc -g ts.c -o ts -L. -ls

执行./ts,嗯:成功了。。。还差点
得到了ts:error while loading shared libraries: libs.so: cannot open shared object file: No such file or directory
系统不能找到我们自己定义的libs.so,那么告诉他,修改变量LD_LIBRARY_PATH,为了方便,写个脚本:e(文件名就叫e,懒得弄长了)
#!/bin/sh
export LD_LIBRARY_PATH=${pwd}:${LD_LIBRARY_PATH}
./ts
执行:./e &
屏幕上就开始不停有信息输出了,当然TS Quit你是看不到的,前面是个死循环,后面会用到这句
3.地址空间,以及线程安全:
如果这样:
./e &开始执行后,稍微等待一下然后再 ./e&,
这个时候屏幕信息会怎么样呢?全局变量count会怎么变化?
会是两个进程交叉输出信息,并且各自的count互不干扰,虽然他们引用了同一个so文件。
也就是说只有代码是否线程安全一说,没有代码是否是进程安全这一说法。
4.库的初始化,解析:
windows下的动态库加载,卸载都会有初始化函数以及卸载函数来完成库的初始化以及资源回收,linux当然也可以实现。
ELF文件本身执行时就会执行一个_init()函数以及_fini()函数来完成这个,我们只要把自己的函数能让系统在这个时候执行
就可以了。
修改我们前面的s.c文件:
C代码 收藏代码
#include <stdio.h>
void my_init(void) __attribute__((constructor)); //告诉gcc把这个函数扔到init section
void my_fini(void) __attribute__((destructor)); //告诉gcc把这个函数扔到fini section
void out_msg(const char *m)
{
printf(" Ok!\n");
}
int i; //仍然是个计数器
void my_init(void)
{
printf("Init ... ... %d\n", ++i);
}
void my_fini(void)
{
printf("Fini ... ... %d\n", ++i);
}

重新制作 libs.so,ts本是不用重新编译了,代码维护升级方便很多。
然后执行: ./e &
可以看到屏幕输出:(不完整信息,只是顺序一样)
Init
Main
OK
Quit
Fini
可以看到我们自己定义的初始化函数以及解析函数都被执行了,而且是在最前面以及最后面。
如果s.c中的sleep(5)没有注释掉,那么有机会:
./e&
./e&连续执行两次,那么初始化函数和解析函数也会执行两次,虽然系统只加载了一次libs.so。
如果sleep时候kill 掉后台进程,那么解析函数不会被执行。
5.使用我们自己库里的函数替换系统函数:
创建一个新的文件b.c:我们要替换系统函数malloc以及free(可以自己写个内存泄露检测工具了)
C代码 收藏代码
#include <stdio.h>
void* malloc(int size)
{
printf("My malloc\n");
return NULL;
}
void free(void* ad)
{
printf("My free\n");
}

老规矩,编译链接成一个so文件:得到libb.so
gcc -fPIC -g -c b.c -o libb.o
gcc -g -shared -Wl,-soname,libb.so -o libb.so -lc
修改s.c:重新生成libs.so
C代码 收藏代码
void out_msg()
{
int *p;
p = (int*)malloc(100);
free(p);
printf("Stop Ok!\n");
}

修改脚本文件e:
#!/bin/sh
export LD_PRELOAD=${pwd}libb.so:${LD_PRELOAD}
export LD_LIBRARY_PATH=${pwd}:${LD_LIBRARY_PATH}
./ts
关键就在LD_PRELOAD上了,这个路径指定的so将在所有的so之前加载,并且符号会覆盖后面加载的so文件中的符号。如果可执行文件的权限不合适(SID),这个变量会被忽略。
执行:./e &
嗯,可以看到我们的malloc,free工作了。
暂时就想到这么多了。
linux so
2017-04-05 15:03:28 kokiafans 阅读数 2
http://mypyg.iteye.com/blog/845915

牵扯到ELF格式,gcc编译选项待补,简单实用的说明一下,对Linux下的so文件有个实际性的认识。
1.so文件是什么?
2.怎么生成以及使用一个so动态库文件?
3.地址空间,以及线程安全.
4.库的初始化,解析:
5.使用我们自己库里的函数替换系统函数:
//-------------------------------------------------------------------------------
1.so文件是什么?
也是ELF格式文件,共享库(动态库),类似于DLL。节约资源,加快速度,代码升级简化。
知道这么多就够了,实用主义。等有了印象再研究原理。
2.怎么生成以及使用一个so动态库文件?
先写一个C文件:s.c
C代码 收藏代码
#include <stdio.h>
int count;
void out_msg(const char *m)
{//2秒钟输出1次信息,并计数
for(;;) {printf("%s %d\n", m, ++count); sleep(2);}
}

编译:得到输出文件libs.o
gcc -fPIC -g -c s.c -o libs.o

链接:得到输出文件libs.so
gcc -g -shared -Wl,-soname,libs.so -o libs.so libs.o -lc

一个头文件:s.h
C代码 收藏代码
#ifndef _MY_SO_HEADER_
#define _MY_SO_HEADER_
void out_msg(const char *m);
#endif

再来一个C文件来引用这个库中的函数:ts.c
C代码 收藏代码
#include <stdio.h>
#include "s.h"
int main(int argc, char** argv)
{
printf("TS Main\n");
out_msg("TS ");
sleep(5); //这句话可以注释掉,在第4节的时候打开就可以。
printf("TS Quit\n");
}

编译链接这个文件:得到输出文件ts
gcc -g ts.c -o ts -L. -ls

执行./ts,嗯:成功了。。。还差点
得到了ts:error while loading shared libraries: libs.so: cannot open shared object file: No such file or directory
系统不能找到我们自己定义的libs.so,那么告诉他,修改变量LD_LIBRARY_PATH,为了方便,写个脚本:e(文件名就叫e,懒得弄长了)
#!/bin/sh
export LD_LIBRARY_PATH=${pwd}:${LD_LIBRARY_PATH}
./ts
执行:./e &
屏幕上就开始不停有信息输出了,当然TS Quit你是看不到的,前面是个死循环,后面会用到这句
3.地址空间,以及线程安全:
如果这样:
./e &开始执行后,稍微等待一下然后再 ./e&,
这个时候屏幕信息会怎么样呢?全局变量count会怎么变化?
会是两个进程交叉输出信息,并且各自的count互不干扰,虽然他们引用了同一个so文件。
也就是说只有代码是否线程安全一说,没有代码是否是进程安全这一说法。
4.库的初始化,解析:
windows下的动态库加载,卸载都会有初始化函数以及卸载函数来完成库的初始化以及资源回收,linux当然也可以实现。
ELF文件本身执行时就会执行一个_init()函数以及_fini()函数来完成这个,我们只要把自己的函数能让系统在这个时候执行
就可以了。
修改我们前面的s.c文件:
C代码 收藏代码
#include <stdio.h>
void my_init(void) __attribute__((constructor)); //告诉gcc把这个函数扔到init section
void my_fini(void) __attribute__((destructor)); //告诉gcc把这个函数扔到fini section
void out_msg(const char *m)
{
printf(" Ok!\n");
}
int i; //仍然是个计数器
void my_init(void)
{
printf("Init ... ... %d\n", ++i);
}
void my_fini(void)
{
printf("Fini ... ... %d\n", ++i);
}

重新制作 libs.so,ts本是不用重新编译了,代码维护升级方便很多。
然后执行: ./e &
可以看到屏幕输出:(不完整信息,只是顺序一样)
Init
Main
OK
Quit
Fini
可以看到我们自己定义的初始化函数以及解析函数都被执行了,而且是在最前面以及最后面。
如果s.c中的sleep(5)没有注释掉,那么有机会:
./e&
./e&连续执行两次,那么初始化函数和解析函数也会执行两次,虽然系统只加载了一次libs.so。
如果sleep时候kill 掉后台进程,那么解析函数不会被执行。
5.使用我们自己库里的函数替换系统函数:
创建一个新的文件b.c:我们要替换系统函数malloc以及free(可以自己写个内存泄露检测工具了)
C代码 收藏代码
#include <stdio.h>
void* malloc(int size)
{
printf("My malloc\n");
return NULL;
}
void free(void* ad)
{
printf("My free\n");
}

老规矩,编译链接成一个so文件:得到libb.so
gcc -fPIC -g -c b.c -o libb.o
gcc -g -shared -Wl,-soname,libb.so -o libb.so -lc
修改s.c:重新生成libs.so
C代码 收藏代码
void out_msg()
{
int *p;
p = (int*)malloc(100);
free(p);
printf("Stop Ok!\n");
}

修改脚本文件e:
#!/bin/sh
export LD_PRELOAD=${pwd}libb.so:${LD_PRELOAD}
export LD_LIBRARY_PATH=${pwd}:${LD_LIBRARY_PATH}
./ts
关键就在LD_PRELOAD上了,这个路径指定的so将在所有的so之前加载,并且符号会覆盖后面加载的so文件中的符号。如果可执行文件的权限不合适(SID),这个变量会被忽略。
执行:./e &
嗯,可以看到我们的malloc,free工作了。
暂时就想到这么多了。
2018-07-25 19:10:00 weixin_33825683 阅读数 5

Linux Library Types:

There are two Linux C/C++ library types which can be created:

  • Static libraries (.a):
    Library of object code which is linked with, and becomes part of the application.
  • Dynamically linked shared object libraries (.so):
    There is only one form of this library but it can be used in two ways.
    Dynamically linked at run time. The libraries must be available during compile/link phase. The shared objects are not included into the executable component but are tied to the execution.
    Dynamically loaded/unloaded and linked during execution (i.e. browser plug-in) using the dynamic linking loader system functions.

A .a file is a static library, while a .so file is a shared object dynamic library similar to a DLL on Windows.
A .a can included as part of a program during the compilation & .so can imported, while a program loads.

.a是静态库。
.so是动态库。

When you link against the *.a, the code from the library is included in the executable itself and the executable can be run without requiring the *.a file to be present.
When you link against the *.so, that is not the case and the *.so file must be present at runtime.

.a的方式,.a中的内容是包含在二进制文件中的,所以二进制文件运行的时候不需要*.a file。

Static Libraries: (.a)

As a follow on, a .a file is an "ar" archive.
Not unlike a tar archive, it stores .o or object files, allowing them to be pulled out of the archive, and linked into a program, among other things. You could use ar to store other files if you wanted.

Create library "libctest.a"
ar -cvq libctest.a ctest1.o ctest2.o
get a listing of the members of an ar file

You can get a listing of the members of an ar file with the -t parameter, for instance:

linux下,在ffmpeg目录下

 ar -t libavformat/libavformat.a

运行结果:

[root@localhost libavformat]# ar -t libavformat.a
3dostr.o
...
mov.o
...
yuv4mpegdec.o
yuv4mpegenc.o
Linking with the library
cc -o executable-name prog.c libctest.a
cc -o executable-name prog.c -L/path/to/library-directory -lctest

Dynamically Linked "Shared Object" Libraries: (.so)

A .so file is a "shared object" file, and has a lot more information available to the linker so that members can be linked in to a loading program as rapidly as possible.

References:

https://stackoverflow.com/questions/12293530/what-is-the-difference-between-so-and-a-files
https://unix.stackexchange.com/questions/13192/what-is-the-difference-between-a-and-so-file
http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html

linux so
2012-12-28 16:35:26 iteye_2768 阅读数 15

来源:http://mypyg.iteye.com/blog/845915

 

1.so文件是什么?
也是ELF格式文件,共享库(动态库),类似于DLL。节约资源,加快速度,代码升级简化。
知道这么多就够了,实用主义。等有了印象再研究原理。
2.怎么生成以及使用一个so动态库文件?
先写一个C文件:s.c

 #include <stdio.h>
 int count;
 void out_msg(const char *m)
 {//2秒钟输出1次信息,并计数
  for(;;) {printf("%s %d\n", m, ++count); sleep(2);}
 }

 编译:得到输出文件libs.o
gcc -fPIC -g -c s.c -o libs.o
链接:得到输出文件libs.so
gcc -g -shared -Wl,-soname,libs.so -o libs.so libs.o -lc

一个头文件:s.h

#ifndef _MY_SO_HEADER_
 #define _MY_SO_HEADER_
 void out_msg(const char *m);
 #endif

 再来一个C文件来引用这个库中的函数:ts.c

#include <stdio.h>
 #include "s.h"
 int main(int argc, char** argv)
 {
  printf("TS Main\n");
  out_msg("TS ");
  sleep(5);  //这句话可以注释掉,在第4节的时候打开就可以。
  printf("TS Quit\n");
 }

 编译链接这个文件:得到输出文件ts
gcc -g ts.c -o ts -L. -ls

执行./ts,嗯:成功了。。。还差点
得到了ts:error while loading shared libraries: libs.so: cannot open shared object file: No such file or directory
系统不能找到我们自己定义的libs.so,那么告诉他,修改变量LD_LIBRARY_PATH,为了方便,写个脚本:e(文件名就叫e,懒得弄长了)
#!/bin/sh
export LD_LIBRARY_PATH=${pwd}:${LD_LIBRARY_PATH}
./ts
执行:./e &
屏幕上就开始不停有信息输出了,当然TS Quit你是看不到的,前面是个死循环,后面会用到这句
3.地址空间,以及线程安全:
如果这样:
./e &开始执行后,稍微等待一下然后再 ./e&,
这个时候屏幕信息会怎么样呢?全局变量count会怎么变化?
会是两个进程交叉输出信息,并且各自的count互不干扰,虽然他们引用了同一个so文件。
也就是说只有代码是否线程安全一说,没有代码是否是进程安全这一说法。
4.库的初始化,解析:
windows下的动态库加载,卸载都会有初始化函数以及卸载函数来完成库的初始化以及资源回收,linux当然也可以实现。
ELF文件本身执行时就会执行一个_init()函数以及_fini()函数来完成这个,我们只要把自己的函数能让系统在这个时候执行
就可以了。
修改我们前面的s.c文件:

#include <stdio.h>
 void my_init(void) __attribute__((constructor)); //告诉gcc把这个函数扔到init section
 void my_fini(void) __attribute__((destructor));  //告诉gcc把这个函数扔到fini section
 void out_msg(const char *m)
 {
  printf(" Ok!\n"); 
 }
 int i; //仍然是个计数器
 void my_init(void)
 {
  printf("Init ... ... %d\n", ++i);
 }
 void my_fini(void)
 {
  printf("Fini ... ... %d\n", ++i);
 }

 重新制作 libs.so,ts本是不用重新编译了,代码维护升级方便很多。
然后执行: ./e &
可以看到屏幕输出:(不完整信息,只是顺序一样)
Init
Main
OK
Quit
Fini
可以看到我们自己定义的初始化函数以及解析函数都被执行了,而且是在最前面以及最后面。
如果s.c中的sleep(5)没有注释掉,那么有机会:
./e&
./e&连续执行两次,那么初始化函数和解析函数也会执行两次,虽然系统只加载了一次libs.so。
如果sleep时候kill 掉后台进程,那么解析函数不会被执行。
5.使用我们自己库里的函数替换系统函数:
创建一个新的文件b.c:我们要替换系统函数malloc以及free(可以自己写个内存泄露检测工具了)

#include <stdio.h>
 void* malloc(int size)
 {
  printf("My malloc\n");
  return NULL;
 }
 void free(void* ad)
 {
  printf("My free\n");
 }

 老规矩,编译链接成一个so文件:得到libb.so
gcc -fPIC -g -c b.c -o libb.o
gcc -g -shared -Wl,-soname,libb.so -o libb.so -lc
修改s.c:重新生成libs.so

void out_msg()
 {
  int *p;
  p = (int*)malloc(100);
  free(p);
  printf("Stop Ok!\n");
 }

 修改脚本文件e:
#!/bin/sh
export LD_PRELOAD=${pwd}libb.so:${LD_PRELOAD}
export LD_LIBRARY_PATH=${pwd}:${LD_LIBRARY_PATH}
./ts
关键就在LD_PRELOAD上了,这个路径指定的so将在所有的so之前加载,并且符号会覆盖后面加载的so文件中的符号。如果可执行文件的权限不合适(SID),这个变量会被忽略。
执行:./e &
嗯,可以看到我们的malloc,free工作了。

 

 

linux so

阅读数 270

博文 来自: fengyv

linux .so read

阅读数 549

Linux的共享库so

阅读数 191

Call .so in Linux

阅读数 603

没有更多推荐了,返回首页