linux 概念

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Windows下的.dll文件和Linux下的.so文件

在写代码生成这些文件时,区别在于:

1、.so文件没有入口函数的概念,.dll文件有,但却不是必须的。

2、.so会导出文件中定义的所有符号(主要是函数),.dll只导出指定的函数,指定的

方式有两种

a、用dllexport关键词修饰需要导出的函数

b、在module definition file里面定义要导出的函数

3、.so文件是elf格式的,可以不连接某些静态库,而等应用程序去连接。.dll需要连接静态库

可以动态链接的库,在Windows上是dynamic link library (DLL),在UNIX或Linux上是SharedLibrary。库文件是预先编译链接好的可执行文件,存储在计算机的硬盘上。大多数情况下,

同一时间多个应用可以使用一个库的同一份拷贝,操作系统不需要加载这个库的多个实例。

@DLL文件

可以使用两种方法将公共符号导入到应用程序中或从DLL 导出函数:

1、生成DLL 时使用模块定义(.DEF) 文件。

2、在主应用程序的函数定义中使用__declspec(dllimport) 或__declspec(dllexport) 关键字。

使用.DEF 文件

模块定义(.DEF) 文件是包含一个或多个描述各种DLL 属性的Module 语句的文本文件。如果不使用

__declspec(dllimport) 或__declspec(dllexport) 导出DLL 函数,则DLL 需要.DEF 文件。

可以使用.DEF 文件导入到应用程序中或从DLL 导出。

例如:

LIBRARY "DLL的name"

DESCRIPTION 'DLL的name Windows Dynamic Link Library'

EXPORTS

函数名; Explicit exports can go here

LIBRARY "xxx_dll"

EXPORTS

add PRIVAT

使用__declspec

32 位版的Visual C++ 用__declspec(dllimport) 和__declspec(dllexport) 取代以前在16 位版的

Visual C++ 中使用的__export 关键字。不使用__declspec(dllimport) 也能正确编译代码,

但使用

__declspec(dllimport) 使编译器可以生成更好的代码。编译器之所以能够生成更好的代码,是因为它

十分清楚函数是否在DLL 中,因此可以生成跳过间接级别的代码,而在跨DLL 边界的函数中通常存在

这些间接代码。但是,必须使用__declspec(dllimport) 才能导入DLL 中使用的变量。

如果有正确的.DEF 文件EXPORTS 节,则不需要__declspec(dllexport)。添加__declspec(dllexport)

是为了提供不使用.DEF 文件从.EXE 或.DLL 导出函数的简单方法。Win32 可移植可执行文件格式旨在

最小化为修改导入而必须访问的页数。为此,它将所有程序的所有导入地址都放在一个称为“导入地址表”

的位置。这使得加载程序在访问这些导入时可以只修改一两页。

例如:

#ifndef LIB_H

#define LIB_H

extern "C" int _declspec(dllexport)add(int x,int y);

#endif

@SO文件

就说一个Java中调用so的问题,假如你在Java程序中要调用一个名叫sample的动态库,即如下:

static { System.loadLibrary("sample"); }

那生成的so文件前面必须加lib(最起码在Redhat中是这样的),即

gcc -o libsample.so -shared -I sample.c

最后在Java运行时要记得把动态链接库的路径加进来

java -Djava.library.path=

一、公约

1. 库的命名习惯

一个Linux DLL 有三个不同名字的文件组成

soname 文件

lib + 链接库名字+ .so + .版本号

每当链接库接口改变时都递增版本号。soname 文件其实只是一个符号链接而已,指向他的real name 文件。

real name 文件

lib + 链接库名字+ .so + .版本号.次版本号.发行号

发行号是可选的。该文件包含实际代码。

linker name 文件

lib + 链接库名字+ .so

编译器以这个名字来请求指定的链接库。

当程序在内部列出所需要的链接库时,仅仅使用soname。当你创建一个链接库时,使用real name。安装一个新的链接库时,把它复制到一个DLL文件夹里,然后运行程序ldconfig(8)。ldconfig 检查存在的real name 文件,并且创建指向它的符号链接soname 文件。ldconfig 还做一件事情就是建立cache 文件/etc/ld.so.cache

ldconfig 不会创建linker name 文件,但是一般性linker name 文件在安装链接库的时候创建。linker name 文件也只是一个符号链接,指向最新的soname 文件或real name 文件。建议指向soname 文件,因为当你更新库以后,在编译器链接的时候,一般总是想使用新的库。

2. 库的放置

DLL 必须放置在文件系统的指定位置。多数开源软件遵守GNU 标准:当分发源代码的时候,库默认安装在/usr/local/lib,命令安装在/usr/local/bin。该标准还定义了如何重写这些默认标准以及如何调用安装程序。

Filesystem Hierarchy Standard(FHS) 规定:多数库应安装在/usr/lib,启动时需要的库安装在/lib,非系统库应安装在/usr/local/lib

GNU 标准是针对开发人员的,FHS 是针对发行者的。

二、库是如何被使用的

在基于GNU glibc 的系统上,包括所有linux 系统,ELF 可执行二进制文件的运行自动导致程序加载器被加载并且运行。在linux 下,加载器是/lib/ld-linux.so.X(X是版本号)。然后加载器搜索、加载程序所要使用的动态链接库。

被搜索的文件夹列表保存在文件/etc/ld.so.conf 里。

在程序启动的时候搜索这些文件夹是很没有效率的,所以实际上使用缓存。ldconfig(8) 默认读取/etc/ld.so.conf 文件,在DLL 文件夹里创建合适的符号链接,在/etc/ld.so.cache 里写入一个缓存。缓存大大加速了库的读取。所以,当一个DLL 被添加、删除时,或DLL文件夹被改变时都需要运行ldconfig 程序,当安装了一个新的DLL 时,由软件包管理器自动运

相关文档
最新文档