Linux下创建动态库的简明教程 (linux 创建动态库)

动态库是动态链接库的缩写,是一种可以在程序运行时动态加载的代码储存方式。相比于静态库,动态库不仅更加灵活,而且可以节省存储和运行内存。

本文将介绍如何在Linux系统中创建动态库。

之一步:准备代码文件

我们需要准备要打包成动态库的代码文件。例如,我们有一个名为add.c的代码文件,其中包含了一个简单的加法函数:

“`

int add(int a, int b) {

return a + b;

}

“`

第二步:编译代码文件

接下来,我们需要将代码文件编译成目标文件。在Linux系统中,可以使用gcc编译器执行以下命令:

“`

gcc -Wall -c -fPIC add.c -o add.o

“`

其中,-Wall选项表示打开所有警告信息,-c选项表示只编译不链接,-fPIC选项表示生成位置无关代码(Position-Independent Code),-o选项表示指定输出目标文件的文件名。

在执行完上述命令后,将会生成名为add.o的目标文件,该文件将用作下一步的输入。

第三步:生成动态库文件

在完成了目标文件的编译后,我们需要使用gcc编译器生成动态库文件。执行以下命令:

“`

gcc -shared -o libadd.so add.o

“`

其中,-shared选项表示生成共享目标文件(Shared Object File),-o选项指定输出动态库文件的名称。在本例中,生成的动态库文件名称为libadd.so。

第四步:设置动态库路径

为了在程序中正确使用动态库,我们需要指定动态库路径。可以使用以下命令将libadd.so添加到系统动态库路径:

“`

sudo cp libadd.so /usr/lib

“`

上述命令将动态库文件复制到/usr/lib目录下,若该目录路径不存在,则需手动创建目录。

第五步:使用动态库

我们可以测试动态库是否正常工作。编写一个测试代码test.c,调用add()函数并编译生成可执行文件。在编译过程中,需要指定动态库的名称和位置:

“`

gcc test.c -o test -L/usr/lib -ladd

“`

其中,-L选项表示指定动态库搜索路径,-l选项用于指定要链接的动态库的名称。在本例中,链接的是名为libadd.so的动态库。

运行可执行文件,如果输出结果为3,则表明动态库已经成功工作。

结论

本文介绍了在Linux系统中创建动态库的过程。动态库具有灵活、运行时加载等优点,在程序开发中非常有用。但是需要注意,动态库需要进行额外的设置和管理,例如设置动态库路径、管理库的版本等。希望读者在使用动态库时注意所有这些问题,以保证程序的良好运作。

相关问题拓展阅读:

files和lib是不是相同

makefile

dll和lib文件的区别

vanezuo

原创

关注

0点赞·591人阅读

版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明

(1)lib是编译时需要的,dll是运行时需要的。

如果要完成源代码的编译,有lib就够了。

如果也使动态连接的程序运行起来,有dll就够了。

在开发和调试阶段,当然更好都有。

(2) 一般的闭冲袭动态库程序有lib文件和dll文件。lib文件是必须在编译期就连接到应用程序中的,而dll文件是运行期才会被调用的。如果有dll文件,那么 对应的lib文件一般是一些索引信息,具体的实现在dll文件中。如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。静态编 译的lib文件有好处:给用户安装时就不需要再挂动态库了。但也有缺点,就是导致应用程序比较大,而且失去了动态库的灵活性,在版本升级时,同时要发布新 的应用程序才行。

(3)在动态库的情况下,有两个文件,一个是引入库(判州.LIB)文件,一个是DLL文件,引入库文件包含被DLL导出的函数 的名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到所需要使用的DLL文件,库中的函数和数据并不复制到可执行文件中,因此在应用 程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行是再把程序代码和被调用的函数代 码链接起来,从而节省了内存资源。从上面的说明可以看出,DLL和.LIB文件必须随应用程序一起发行,否则应用程序将会产生错误。

(以下是另外一轿兄篇文章的内容)

  1、引言

动态库(Dynamic Link Library abbr,DLL)技术是程序设计中经常采用的技术。其目的减少程序的大小,节省空间,提高效率,具有很高的灵活性。采用动态库技术对于升级软件版本更加容易。与静态库(Static Link Library)不同,动态库里面的函数不是执行程序本身的一部分,而是根据执行需要按需载入,其执行代码可以同时在多个程序享。

在Windows和Linux操作系统中,都可采用这种方式进行软件设计,但他们的调用方式以及程序编制方式不尽相同。本文首先分析了在这两种操作系统中 通常采用的动态库调用方法以及程序编制方式,然后分析比较了这两种方式的不同之处,最后根据实际移植程序经验,介绍了将VC++编制的Windows动态 库移植到Linux下的方法。

2、动态库技术

2.1 Windows动态库技术

动态链接库是实现Windows应用程序共享资源、节省内存空间、提高使用效率的一个重要技术手段。常见的动态库包含外部函数和资源,也有一些动态库只包 含资源,如Windows字体资源文件,称之为资源动态链接库。通常动态库以.dll,.drv、.fon等作为后缀。相应的windows静态库通常 以.lib结尾,Windows自己就将一些主要的系统功能以动态库模块的形式实现。

Windows动态库在运行时被系统加载到进程的虚拟空间中,使用从调用进程的虚拟地址空间分配的内存,成为调用进程的一部分。DLL也只能被该进程的线 程所访问。DLL的句柄可以被调用进程使用;调用进程的句柄可以被DLL使用。DLL模块中包含各种导出函数,用于向外界提供服务。DLL可以有自己的数 据段,但没有自己的堆栈,使用与调用它的应用程序相同的堆栈模式;一个DLL在内存中只有一个实例;DLL实现了代码封装性;DLL的编制与具体的编程语 言及编译器无关,可以通过DLL来实现混合语言编程。DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。

根据调用方式的不同,对动态库的调用可分为静态调用方式和动态调用方式。

(1)静态调用,也称为隐式调用,由编译系统完成对DLL的加载和应用程序结束时DLL卸载的编码(Windows系统负责对DLL调用次数的计数),调 用方式简单,能够满足通常的要求。通常采用的调用方式是把产生动态连接库时产生的.LIB文件加入到应用程序的工程中,想使用DLL中的函数时,只须在源 文件中声明一下。 LIB文件包含了每一个DLL导出函数的符号名和可选择的标识号以及DLL文件名,不含有实际的代码。Lib文件包含的信息进入到生成的应用程序中,被调 用的DLL文件会在应用程序加载时同时加载在到内存中。

(2)动态调用,即显式调用方式,是由编程者用API函数加载和卸载DLL来达到调用DLL的目的,比较复杂,但能更加有效地使用内存,是编制大型应用程序时的重要方式。在Windows系统中,与动态库调用有关的函数包括:

①LoadLibrary(或MFC 的AfxLoadLibrary),装载动态库。

②GetProcAddress,获取要引入的函数,将符号名或标识号转换为DLL内部地址。

③FreeLibrary(或MFC的AfxFreeLibrary),释放动态链接库。

在windows中创建动态库也非常方便和简单。在Visual C++中,可以创建不用MFC而直接用C语言写的DLL程序,也可以创建基于MFC类库的DLL程序。每一个DLL必须有一个入口点,在VC++中, DllMain是一个缺省的入口函数。DllMain负责初始化(Initialization)和结束(Termination)工作。动态库输出函数 也有两种约定,分别是基于调用约定和名字修饰约定。DLL程序定义的函数分为内部函数和导出函数,动态库导出的函数供其它程序模块调用。通常可以有下面几 种方法导出函数:

①采用模块定义文件的EXPORT部分指定要输入的函数或者变量。

②使用MFC提供的修饰符号_declspec(dllexport)。

③以命令行方式,采用/EXPORT命令行输出有关函数。

在windows动态库中,有时需要编写模块定义文件(.DEF),它是用于描述DLL属性的模块语句组成的文本文件。

2.2 Linux共享对象技术

在Linux操作系统中,采用了很多共享对象技术(Shared Object),虽然它和Windows里的动态库相对应,但它并不称为动态库。相应的共享对象文件以.so作为后缀,为了方便,在本文中,对该概念不进 行专门区分。Linux系统的/lib以及标准图形界面的/usr/X11R6/lib等目录里面,就有许多以so结尾的共享对象。同样,在Linux 下,也有静态函数库这种调用方式,相应的后缀以.a结束。Linux采用该共享对象技术以方便程序间共享,节省程序占有空间,增加程序的可扩展性和灵活 性。Linux还可以通过LD-PRELOAD变量让开发人员可以使用自己的程序库中的模块来替换系统模块。

同Windows系统一样,在Linux中创建和使用动态库是比较容易的事情,在编译函数库源程序时加上-shared选项即可,这样所生成的执行程序就 是动态链接库。通常这样的程序以so为后缀,在Linux动态库程序设计过程中,通常流程是编写用户的接口文件,通常是.h文件,编写实际的函数文件, 以.c或.cpp为后缀,再编写makefile文件。对于较小的动态库程序可以不用如此,但这样设计使程序更加合理。

编译生成动态连接库后,进而可以在程序中进行调用。在Linux中,可以采用多种调用方式,同Windows的系统目录(../system32等)一 样,可以将动态库文件拷贝到/lib目录或者在/lib目录里面建立符号连接,以便所有用户使用。下面介绍Linux调用动态库经常使用的函数,但在使用 动态库时,源程序必须包含dlfcn.h头文件,该文件定义调用动态链接库的函数的原型。

(1)_打开动态链接库:dlopen,函数原型void *dlopen (const char *filename, int flag);

dlopen用于打开指定名字(filename)的动态链接库,并返回操作句柄。

(2)取函数执行 void *dlsym(void *handle, char *symbol);

dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函数的执行代码地址。

(3)关闭动态链接库:dlclose,函数原型为: int dlclose (void *handle);

dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

(4)动态库错误函数:dlerror,函数原型为: const char *dlerror(void); 当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。

在取到函数执行地址后,就可以在动态库的使用程序里面根据动态库提供的函数接口声明调用动态库里面的函数。在编写调用动态库的程序的makefile文件时,需要加入编译选项-rdynamic和-ldl。

除了采用这种方式编写和调用动态库之外,Linux操作系统也提供了一种更为方便的动态库调用方式,也方便了其它程序调用,这种方式与Windows系统 的隐式链接类似。其动态库命名方式为“lib*.so.*”。在这个命名方式中,之一个*表示动态链接库的库名,第二个*通常表示该动态库的版本号,也可 以没有版本号。在这种调用方式中,需要维护动态链接库的配置文件/etc/ld.so.conf来让动态链接库为系统所使用,通常将动态链接库所在目录名 追加到动态链接库配置文件中。如具有X window窗口系统发行版该文件中都具有/usr/X11R6/lib,它指向X window窗口系统的动态链接库所在目录。为了使动态链接库能为系统所共享,还需运行动态链接库的管理命令./in/ldconfig。在编译所引 用的动态库时,可以在gcc采用–l或-L选项或直接引用所需的动态链接库方式进行编译。在Linux里面,可以采用ldd命令来检查程序依赖共享库。

3、两种系统动态库比较分析

Windows和Linux采用动态链接库技术目的是基本一致的,但由于操作系统的不同,他们在许多方面还是不尽相同,下面从以下几个方面进行阐述。

(1)动态库程序编写,在Windows系统下的执行文件格式是PE格式,动态库需要一个DllMain函数作为初始化的人口,通常在导出函数的声明时需 要有_declspec(dllexport)关键字。Linux下的gcc编译的执行文件默认是ELF格式,不需要初始化入口,亦不需要到函数做特别声 明,编写比较方便。

(2)动态库编译,在windows系统下面,有方便的调试编译环境,通常不用自己去编写makefile文件,但在linux下面,需要自己动手去编写makefile文件,因此,必须掌握一定的makefile编写技巧,另外,通常Linux编译规则相对严格。

(3)动态库调用方面,Windows和Linux对其下编制的动态库都可以采用显式调用或隐式调用,但具体的调用方式也不尽相同。

(4)动态库输出函数查看,在Windows中,有许多工具和软件可以进行查看DLL中所输出的函数,例如命令行方式的dumpbin以及VC++工具中 的DEPENDS程序。在Linux系统中通常采用nm来查看输出函数,也可以使用ldd查看程序隐式链接的共享对象文件。

(5)对操作系统的依赖,这两种动态库运行依赖于各自的操作系统,不能跨平台使用。因此,对于实现相同功能的动态库,必须为两种不同的

操作系统提供不同的动态库版本。

lib和dll文件的区别和联系

:09

lib和dll

lib和dll文件的区别和联系

.dll是在你的程序运行的时候才连接的文件,因此它是一种比较小的可执行文件格式,.dll还有其他的文件格式如.ocx等,所有的.dll文件都是可执行。

.lib是在你的程序编译连接的时候就连接的文件,因此你必须告知编译器连接的lib文件在那里。一般来说,与动态连接文件相对比,lib文件也被称为是静态连接库。当你把代码编译成这几种格式的文件时,在以后他们就不可能再被更改。如果你想使用lib文件,就必须:

1 包含一个对应的头文件告知编译器lib文件里面的具体内容

2 设置lib文件允许编译器去查找已经编译好的二进制代码

如果你想从你的代码分离一个dll文件出来代替静态连接库,仍然需要一个lib文件。这个lib文件将被连接到程序告诉操作系统在运行的时候你想用到什么dll文件,一般情况下,lib文件里有相应的dll文件的名字和一个指明dll输出函数入口的顺序表。如果不想用lib文件或者是没有lib文件,可以用WIN32 API函数LoadLibrary、GetProcAddress。事实上,我们可以在Visual C++ IDE中以二进制形式打开lib文件,大多情况下会看到ASCII码格式的C++函数或一些重载操作的函数名字。

一般我们最主要的关于lib文件的麻烦就是出现unresolved symble 这类错误,这就是lib文件连接错误或者没有包含.c、.cpp文件到工程里,关键是如果在C++工程里用了C语言写的lib文件,就必需要这样包含:

extern “C”

{

#include “myheader.h”

}

这是因为C语言写的lib文件没有C++所必须的名字破坏,C函数不能被重载,因此连接器会出错。

===============================

在VC中不用MFC如何制作dll

方法一:使用export 和 import

在VC中建立一个Console Application,建立2个文件:Dll.h 和 Dll.cpp

Dll.h

#ifdef MYLIBAPI

#else

#define MYLIBAPI extern “C” _declspec (dllimport)

#end if

MYLIBAPI int Add (int iLeft, int iRight)

MYLIBAPI int Sub (int iLeft, int iRight)

Dll.cpp

#define MYLIBAPI extern “C” _declspec (dllexport)

#include “Dll.h”

int Add (int iLeft, int iRight)

{

return iLeft + iRight ;

}

int Sub (int iLeft, int iRight)

{

return iLeft – iRight ;

}

保存文件。

在Project->setting->link 最下面加上 “/dll”, “/”之前一定要与前一项

有空格。

然后编译,就可以在debug 或 release下面找到dll 和 lib 文件了

使用的时候包含dll.h文件

方法二:使用def文件

建立一个console application, 建立2个文件dll.h 和 dll.cpp

Dll.h

int Add (int iLeft, int iRight) ;

int Sub (int iLeft, int iRight) ;

Dll.cpp

#include “Dll.h”

int Add (int iLeft, int iRight)

{

return iLeft + iRight ;

}

int Sub (int iLeft, int iRight)

{

return iLeft – iRight ;

}

然后再当前目录下面建立一个.def文件,文件名更好和要输出的dll名字一样,扩展名

为.def, 里面写上:

LIBRARY dllname.dll

EXPORTS

Add @1

Add @2

然后将这个文件添加到工程中,

在link中设置 /dll, 然后编译

在debug或release中就可以找到dll和lib了

使用的时候加上dll.h文件

不是唤陆拿,files和lib是不同的文件夹,files文件夹存放程悉陪序文件,而和搭lib文件夹存放函数库文件。

linux下用GCC连接器中 -shared 生成的动态库文件不能连接。

你好!对于此问题可以 locate libXXX.so (如果你的文件系统比以前有了变化,如安装了可能是需要的库的开发包,则需要 sudo updatedb 一下)

然后如果发现了libXXX.so的确存在,就把libXXX.so所在的目录加入到 /etc/ld.so.conf 中,或者在 /笑毕etc/ld.so.conf.d/ 下新建一文件,如 XXX.conf ,其内容是libXXX.so所在的目录。

如果发现libXXX.so不存在,你可带雹能没安装包含库的程序。一般google一下“XXX linux”就能找到相应的软件。

如果提示是error while loading shared libraries: libXXX.so,但你的系统上有libXXX.so.5,你可以为libXXX.so.5

做一个软链接 ln -s libXXX.so.5 libXXX.so

举个例子,如执行一个ACE开发包中的样例程序时,出现以下提示:

./logging_app: error while loading shared libraries: libACE.so.5.4.7: cannot open shared object file: No such file or directory

# locate libACE.so.5.4.7

/opt/ace/ace/libACE.so.5.4.7

/蠢升帆opt/ace/lib/libACE.so.5.4.7

# vi ace.conf

ace.conf中只有一行: /opt/ace/lib

然后再执行 ldconfig

OK,现在执行logging_app就没有错误了。

linux 创建动态库的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于linux 创建动态库,Linux下创建动态库的简明教程,files和lib是不是相同,linux下用GCC连接器中 -shared 生成的动态库文件不能连接。的信息别忘了在本站进行查找喔。


数据运维技术 » Linux下创建动态库的简明教程 (linux 创建动态库)