面试后的小尝试(linux下.so共享文件的创建)

昨天,参加了一场笔试和面试。对于我这个初入软件,想要转行的名符其实的“菜鸟”来说,打击不少,几个月的“苦读”,原以为基本知识涉猎的差不多的我,迎来了一次真正的笔试与面试。两个小时的笔试,对于我来说,内容有些难度,涉及到一些数据结构的知识,也让只会看书,疏于“上机”的我感到一片茫然。毕竟,理念到实践的转换与成熟运用需要真枪实弹的练习,而我只是学会了“纸上谈兵”。具体的细节,待我把所有的相关的知识梳理好之后再发一篇博文。面试的大哥问了我关于.so文件的内容,我真心不太懂,回家的路上我一直在考虑这个问题。先把目前完全一无所知的知识及时补充一下。下面我把自己的理论与实践写出来,供大家批判。

参照了博文http://hi.baidu.com/buptwinnie/item/6031fdcfeecf752ca1b50aff,先表示感谢。

.so共享文件相对于linux来说,就如同.dll文件相对于windows。windows下的.dll文件编程,可以建立专门的.dll文件,将程序编写好导出,生成文件。然后在主文件中导入调用就可以实现,具体的细节也不是很了解。但对于linux 下的.so文件来说,情况有些不同。下面,我先把自己已经实现的过程贴出来。(环境:WINDOWS7下的32位ubuntu12.10 虚拟机)

  • 先编写被调用的函数文件 add.c ,sub.c,operation.h
  • // operation.h
    #ifndef _OPERATION_H
    #define _OPERATION_H
    
    extern int add(int,int);
    extern int sub(int,int);
    
    #endif
    //add.c
    
    #include "operation.h"
    
    int add(int x,int y)
    {
        return x+y;
    }
    //sub.c
    
    #include "operation.h"
    
    int sub(int x,int y)
    {
       return x-y;
    }
  • 生成共享库文件liboperation.so

     gcc add.c sub.c -fPIC -shared -o liboperation.so
  • 编写主文件test001.c ,在主函数main中调用共享库文件中的函数add(),sub()

    //test001.c
    #include "operation.h"
    #include "stdio.h"
    
    int main()
    {
        int result=0;
        int a=add(3,5);
        int b=sub(8,6);
        result=add(a,b);
    
        printf("the result is : %d",result);
    
    }//不用”#include "operation.h"时,编译也可以成功
  • 将主文件与共享库链接生成可运行文件 test001
gcc test001.c -L. -loperation -o test001

先说明一下几个参数的意思:

-fPIC :参照博客中的解释是此参数实现真实的文件共享,位置固定,所有调用该文件内函数的操作都指向同一个位置。而如果不加此参数,只是调用了副本。(关于这个参数的检验,是否涉及到同步的一些问题,是否需要信号量,临界区等??)

-shared:生成共享库文件

-L:编译链接生成可执行文件时,指定所需要链接的共享库文件.so所在的目录,一般是放在当前目录,所以参数为-L. 别忘了写上.符号表示当前目录。

-l: 编译链接时,编译器会主动将-l后面接的名字XXX前面加上lib,后面加上.so,构成libXXX.so,然后到-L参数所指定的目录寻找该共享库文件。

-o:指定所生成的文件名,在生成共享库时,生成库文件名,在生成可执行文件时,生成可执行文件名。

还有参数-l本例中没有用到

如果我们生成共享库文件与生成可执行文件时不在同一个目录下,那么在编译链接可执行文件时,往往要用-L来寻找共享库文件所在的目录。而如果生成共享库时需要用到的头文件(自己定义的头文件)不在共享库所在的目录内时,就要指定头文件所在的目录。同样,在生成可执行文件时,如果include 某自己编辑的头文件,而该文件不在当前目录里时。都要用到-I参数。语法与-L相同

这时可以先用ldd test001 查看否能找到liboperation.so文件。如果是第一次编写.so共享文件,一定会出现找不到该共享文件的情况liboperation.so=》not found

说明系统找不到该共享文件,因为无法确定其目录,即使该文件编译好到放在了当前目录,也要指定该目录的具体的位置。有的博客上要求修改/etc/ld.so.conf文件,在其后加入该共享文件的目录(本例中是在当前目录),尝试后仍不行(目前原因不明)。于是,采用了第二种方法http://blog.csdn.net/csdnxw/article/details/1650650,在/etc/ld.so.conf.d目录下新建XXX.conf文件,在文件里写上共享文件所在的目录(注意后缀.conf似乎不是必要的,我试着修改过去掉了.conf仍然可以找到,这与系统的一切机制相关了,菜鸟不懂,但看到第一种方法中提到的/etc/ld.so.conf文件中只有include /etc/ld.so.conf.d/*.conf有点不解,似乎要求要有.conf),再执行/sbin/ldconfig命令,这样可执行文件test001,就可以正常运行了。这就能回答面试中提出的那个问题,如果当前文件需要调用的共享库文件提示找不到,该如何解决,可以在bash下运行find / -name liboperation.so找到目录,再将该目录添加到/etc/ld.so.conf.d目录下的某个文件中。

如果想要修改函数的功能,只要修改相应函数的文件,然后重新生成共享文件即可。

PS:第一次写这种技术类的文章分享,的确很不容易,那些乐于分享的人致敬!

面试后的小尝试(linux下.so共享文件的创建)

时间: 2024-10-11 15:51:35

面试后的小尝试(linux下.so共享文件的创建)的相关文章

linux 下的使用 ln 创建 软链接 和 硬链接

linux 下的一个指令 ln 作用: 创建软链接或者硬链接 Linux 系统下每创建一个文件,系统都会为此文件生成一个 index node 简称(inode) ,而每一个文件都包含用户数据(user data) 与 元数据(metadata) 用户数据里记录了文件的真正内容. 元数据里记录的是文件的附加属性,如 文件大小,创建时间,所有者等,其中 上面提到的 index node 就保存在元数据中.在linux 中文件名并不是文件的唯一标识,index onde 才是唯一标示,系统查找文件也

Linux下通过受限bash创建指定权限的账号

在日常业务运维中,有时为了配合解决问题,需要给非运维人员开通系统账号,用于查询日志或代码.通常为了系统安全或避免不必要的误操作等目的,会将账号权限降至最低.下面介绍下在Linux下通过受限bash创建指定权限账号的操作记录: [[email protected] ~]# ln -s /bin/bash /bin/rbash [[email protected] ~]# useradd -s /bin/rbash wangshibo [[email protected] ~]# passwd wa

linux下的静态库创建与查看,及如何查看某个可执行依赖于哪些动态库

linux下的静态库创建与查看,及如何查看某个可执行依赖于哪些动态库 创建静态库:ar -rcs test.a *.o查看静态库:ar -tv test.a解压静态库:ar -x test.a 查看程序依赖的动态库:readelf -a xxx|grep library如:可以看到,下面的交叉程序hello执行依赖于如下两个动态库.[email protected]:~/test$ arm-none-linux-gnueabi-readelf -a hello|grep "library&quo

Linux下的文件夹创建命令使用实践

[文章摘要] 本文以实际的C源程序为样例,介绍了Linux下的文件夹创建命令(mkdir)的用法.为相关开发工作的开展提供了故意的參考. [关键词] C语言  Linux  文件夹创建  makefile  开发 一.mkdir命令简单介绍 mkdir命令用来创建指定名称的文件夹,其命令格式为:mkdir [选项] 文件夹... 当中,[选项]能够是"-m"."-p"或"-v". 此外,文件夹名是区分大写和小写的. 二.本程序流程 本文中的程序用

如何在Linux下使用Gitblit工具创建Git仓库服务

嗨!朋友,今天我们将学习如何在你的Linux服务器或者PC上安装Gitblit工具.首先,我们看看什么是Git,它的功能以及安装Gitblit的步骤.Git是分布式版本控制系统,它强调速度.数据一致性,并且支持分布式.非线性工作流.它最初由Linus Torvalds在2005年为Linux内核设计和开发,使用GPLv2证书,并从此成为软件开发中使用最广泛的版本控制系统. Gitblit是完全开源的软件,它基于纯粹的Java堆栈,被设计以在Git仓库速度和效率方面胜任从小型到极大型的项目.它很容

linux下文件夹的创建、复制、剪切、重命名、清空和删除命令 【转】

转载地址:http://blog.csdn.net/numbibi/article/details/8026841 在home目录下有wwwroot目录,wwwroot下有sinozzz目录,即/home/wwwroot/sinozzz 一.目录创建 在/home/wwwroot目录下新建一个sinozzz123的文件夹 mkdir /home/wwwroot/sinozzz123 二.目录复制 1.把/home/wwwroot/sinozzz里面的文件和文件夹等复制到home/wwwroot/

尝试linux下的debug工具: Visual studio

参考: https://blogs.msdn.microsoft.com/vcblog/2016/03/30/visual-c-for-linux-development/linux下面 sudo apt-get install openssh-server g++ gdb gdbserverWIndoiws下面 Launch the Visual Studio 2017 installer and start a new installation or Modify an existing o

尝试linux下的debug工具: gdb

[email protected]:~/projects/ConsoleApplication1$ cat main.cpp#include <cstdio> int main(){// int a = 1; printf("hello from ConsoleApplication1!\n"); return 0;}[email protected]:~/projects/ConsoleApplication1$ cat CMakeLists.txtcmake_minim

linux下守护进程的创建

最近在学习linux c编程 看到了守护进程的创建,感觉很好玩, 测试环境ubuntu 15.04 下面贴出测试代码 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <sys/param.h> #include <sys/stat.h> #include <time.h> #include <