静态链接库lib和动态链接库dll区别
- 格式:doc
- 大小:163.50 KB
- 文档页数:8
动态连结点和静态连接点的区分标准1. 引言嘿,朋友们!今天咱们聊聊一个看似复杂但其实很有趣的话题——动态连结点和静态连接点。
听上去是不是有点儿高大上?别担心,咱们会把它说得简单易懂,像喝水一样轻松。
首先,你可能会问,啥叫连结点?这其实就是指在计算机网络、程序设计中,用来连接不同组件的那些“点”。
想象一下,你的朋友圈,朋友之间就是那些连结点,咱们一起来搞明白它们之间的区别吧!2. 静态连接点2.1 静态的定义好吧,首先我们来聊聊静态连接点。
就像你身边那些忠实的小伙伴,一直在那儿,纹丝不动。
静态连接点,就是在编程中提前设定好的连接,它们不会随时间而变化,像是石头缝里的那些小草,扎根稳稳的。
这种连接的好处是,它们的稳定性超强,出问题的概率小得可怜。
换句话说,就是你不用担心它们今天想跑、明天想飞。
2.2 使用场景那么,静态连接点一般用在哪呢?这就像在家里装的那些老式灯泡,你一开灯,亮得恰到好处,根本不用担心突然黑掉。
比如说,数据库连接、程序库引用等场景,都是静态连接的典型应用。
它们一旦设置好,后面就可以安心使用,不用老是担心连不上,真是省心!3. 动态连接点3.1 动态的定义接下来,咱们来聊聊动态连接点。
说实话,这种连接就像你身边那些不安分的小伙伴,今天跟这个玩,明天跟那个嗨,变化多端。
动态连接点的特点是,它们可以根据需要随时建立和断开,像变魔术一样。
这种灵活性让它们能在很多场合大显身手,但同时也有个小缺点,稳定性可能会差点儿。
3.2 使用场景动态连接点最常见的场合就是网络通信、实时数据传输等。
想象一下,你的手机连上WiFi,这就是动态连接点在起作用。
它随时可以连接上,也可以随时断开,你可以随心所欲,真的是非常方便。
不过,大家也知道,网络不稳定的时候,有可能会掉线,这时候就得小心了,别让它给你“掉链子”。
4. 总结总的来说,静态连接点和动态连接点各有千秋。
静态连接点稳如泰山,适合那些需要稳定的场合;而动态连接点则灵活多变,适合那些需要随时调整的场合。
com组件和一般dll的区别1.动态链接库与静态链接库的区别。
1.1 静态链接库作为代码的一部分,在编译时被链接。
1.2 动态链接库有两种使用方式:一种是静态加载,即在应用程序启动时被加载;一种是动态加载,即是该动态链接库在被使用时才被应用程序加载。
2.动态链接库和COM组件的区别2.1 动态链接库的表现形式只能是dll[变态该名的除外], COM组件的表现形式可以是dll也可以是exe。
注:其实字体、驱动等也算是动态链接库的一种,这里略去...2.2 动态链接库的生成和编译器及系统相关,在Windows/Linux 下系统,需要分别编译才能使用。
COM组件是二进制编码,在Windows和Linux下可以直接使用,不需要重新编译。
2.3 COM组件是按照COM规范实现的dll或者exe;动态链接库是一个可以导出函数的函数集合。
2.4 动态链接库只能在本机被调用,COM组件支持分布式使用。
com英文为Component Object Model组件对象模型是微软生产软件组件的标准。
它是构造二进制兼容软件组件的规范不管组件应用何种语言编写只要遵循com规范就可以相互直接通信。
提出com规范主要是为了满足1.程序的快速开发可以将一个大型的工程分成若干个com组件同时开发。
2.可以动态的插入或卸载com组件。
3.可以隐藏或封装com组件内部的实现细节。
com组件可以由不同的语言进行编写但com组件之间的通信是通过组件的接口来实现的com组件接口的实现是统一的它采用的是虚拟函数表VTBL形式。
虚拟函数表中包含了组件函数的一组指针我们可以通过这组指针来获取我们想要通信的组件函数的内存地址。
dll动态链接库是包含函数和数据的模块的集合。
它可以导出数据也可以导出函数以供其它的dll调用。
dll的加载可以通过静态链接和动态链接两种方式。
1.静态链接时将所要链接的dll模块以二进制的形式编译进其他模块。
2.动态链接指调用模块在运行时加载DLL使用LoadLibrary函数或LoadLibraryEx函数将dll 加载到进程的地址空间并调用GetProcAddress函数以获取导出的 DLL 函数的地址。
静态链接与动态链接的区别动态链接库、静态库、import库区别动态链接库(Dynamic Linked Library): Windows为应⽤程序提供了丰富的函数调⽤,这些函数调⽤都包含在动态链接库中。
其中有3个最重要的DLL,Kernel32.dll,它包含⽤于管理内存、进程和线程的各个函数;User32.dll,它包含⽤于执⾏⽤户界⾯任务(如窗⼝的创建和消息的传送)的各个函数;GDI32.dll,它包含⽤于画图和显⽰⽂本的各个函数。
静态库(Static Library):函数和数据被编译进⼀个⼆进制⽂件(通常扩展名为.LIB)。
在使⽤静态库的情况下,在编译链接可执⾏⽂件时,链接器从库中复制这些函数和数据并把它们和应⽤程序的其它模块组合起来创建最终的可执⾏⽂件(.EXE⽂件)。
导⼊库(Import Library):在使⽤动态链接库的时候,往往提供两个⽂件:⼀个引⼊库和⼀个DLL。
引⼊库包含被DLL导出的函数和变量的符号名,DLL包含实际的函数和数据。
在编译链接可执⾏⽂件时,只需要链接引⼊库,DLL中的函数代码和数据并不复制到可执⾏⽂件中,在运⾏的时候,再去加载DLL,访问DLL中导出的函数。
在运⾏Windows程序时,它通过⼀个被称作“动态链接”的进程与Windows相接。
⼀个Windows的.EXE⽂件拥有它使⽤不同动态链接库的引⽤,所使⽤的函数即在那⾥。
当Windows程序被加载到内存中时,程序中的调⽤被指向DLL函数的⼊⼝,如果DLL不在内存中,系统就将其加载到内存中。
当链接Windows程序以产⽣⼀个可执⾏⽂件时,你必须链接由编程环境提供的专门的“导⼊库(import library)库”。
这些导⼊库包含了动态链接库名称和所有Windows函数调⽤的引⽤信息。
链接程序使⽤该信息在.EXE⽂件中构造⼀个表,当加载程序时,Windows使⽤它将调⽤转换为Windows函数。
静态库与导⼊库的区别:导⼊库和静态库的区别很⼤,他们实质是不⼀样的东西。
vs2010下lib和dll文件的使用——笔记一、lib文件的简介.lib是一种文件后缀,是Windows操作系统的库文件,有静态lib和动态lib 之分:1)、静态lib文件:将导出的文件的声明和实现都放在lib文件中,此时lib 文件主要包含函数的实现部分(cpp文件),例如类的函数定义。
使用时只需配合相关的头文件,编译后程序将lib文件中的代码嵌入到宿主程序中,也就是最后的exe文件中,此时移除lib文件,程序可以正常运行,即编译后就不需要lib 文件的支持了。
2)、动态lib文件:相当于是一个h头文件,用于支持相应的dll文件的运行。
里面存储的是dll文件中各个导出函数的地址,达到链接主程序与dll文件的目的。
二、dll文件的生成vs2010生成dll文件,生成dll文件的时候需要对应的lib文件才能使用,dll生成方法如下(此处只是生成部分,在使用时还需修改):1)新建工程,选择“win32项目”,注意不是“win32控制台项目”,下一步选择生成dll文件,其余默认;2)添加需要封装的.cpp文件,并加入对应的.h文件,先说明类的封装(也就是类的cpp文件)头文件.hclass __declspec(dllexport) NB (类的头文件中只需修改此处即可){public:private:}其中关键字dllexport说明该类的实现部分需要导出。
源文件.cpp添加一句#include "stdafx.h"即可再说明一下一般函数的封装将函数的定义改为extern"C"__declspec(dllexport) float add(float a, float b);extern"C"__declspec(dllexport) float MIN(float a,float b);float MAX(float a,float b);函数MAX为导出到dll文件中,因此相当于不可见。
DLL的创建与调用1、DLL的概念DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数、变量或类。
这些可以直接拿来使用。
静态链接库与动态链接库的区别:(1)静态链接库与动态链接库都是共享代码的方式。
静态链接库把最后的指令都包含在最终生成的EXE 文件中了;动态链接库不必被包含在最终EXE文件中,EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL文件。
(2)静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。
动态链接库的分类:Visual C++支持三种DLL,它们分别是Non-MFC DLL(非MFC动态库)、MFC Regular DLL(MFC规则DLL)、MFC Extension DLL(MFC扩展DLL)。
非MFC动态库不采用MFC 类库结构,其导出函数为标准的C接口,能被非MFC或MFC编写的应用程序所调用;MFC规则DLL 包含一个继承自CWinApp的类,但其无消息循环;MFC扩展DLL采用MFC的动态链接版本创建,它只能被用MFC类库所编写的应用程序所调用。
2、创建一个DLL2.1 非MFC的DLL2.1.1声明导出函数:extern “C” __declspec(dllexport) int add(int a, int b);其中extern “C”为声明为C编译。
由于C++编译器在编译的时候会造成其函数名的该变,在其他应用程序中导致函数不可调用,而C编译器则不会在编译后改变其函数名。
这样如果用C编译的程序来调用该dll中的函数时,可能会造成找不到该函数。
__declspec(dllexport)表示该函数为DLL输出函数,即其他应用程序可以调用该函数从dll中声明输出函数有两种方式:(1)另外一种方式是采用模块定义(.def) 文件声明,.def文件为链接器提供了有关被链接程序的导出、属性及其他方面的信息。
dll原理DLL原理动态链接库(Dynamic Link Library,简称DLL)是一种Windows 操作系统中常用的库文件,它可以被多个应用程序共享使用,从而避免了重复编写相同的代码。
本文将详细介绍DLL的原理。
一、静态链接与动态链接在介绍DLL原理之前,先来了解一下静态链接和动态链接。
1. 静态链接静态链接是指将程序所需要的库文件在编译时全部打包进可执行文件中。
这样做的好处是程序运行时不需要再加载外部库文件,因此速度较快。
但缺点也很明显,即可执行文件体积较大,在多个程序中使用相同的库时会造成重复浪费。
2. 动态链接动态链接是指在程序运行时才加载所需的库文件。
这样做的好处是节省了内存空间,并且多个程序可以共享同一个库文件。
但缺点也很明显,即运行速度较慢。
二、DLL概述1. DLL定义DLL是一个包含可由多个程序同时使用的代码和数据的库文件。
它可以被多个应用程序共享使用,从而避免了重复编写相同的代码。
2. DLL分类根据DLL所包含函数是否可以被其他应用程序调用,DLL可以分为两种类型:(1)导出函数的DLL导出函数的DLL是指将其中一些函数导出,以便其他应用程序可以调用这些函数。
这种DLL文件通常包含一组API(Application Programming Interface,应用程序编程接口)函数。
(2)内部使用的DLL内部使用的DLL是指不导出任何函数,只供当前进程中的其他模块使用。
这种DLL文件通常包含一些共享数据和实现某些功能的代码。
三、DLL加载过程1. 加载方式当一个应用程序需要调用一个DLL中的函数时,Windows操作系统会自动加载该DLL。
Windows操作系统有两种加载方式:(1)显式链接显式链接是指在编译时就将要使用的DLL文件名和需要调用的函数名写入源代码中,并在程序运行时由操作系统自动加载该DLL文件。
(2)隐式链接隐式链接是指在编译时不将要使用的DLL文件名和需要调用的函数名写入源代码中,而是在程序运行时由操作系统自动搜索并加载相应的DLL文件。
QT开发——动态库静态库的⽣成与调⽤(Qmake和Cmake⽅式)1.理解动态库与静态库区别链接:https:///wonengguwozai/article/details/93195827静态库和动态库最本质的区别就是:该库是否被编译进⽬标(程序)内部。
1.1 静态(函数)库⼀般扩展名为(.a或.lib),这类的函数库通常扩展名为libxxx.a或xxx.lib 。
这类库在编译的时候会直接整合到⽬标程序中,所以利⽤静态函数库编译成的⽂件会⽐较⼤,这类函数库最⼤的优点就是编译成功的可执⾏⽂件可以独⽴运⾏,⽽不再需要向外部要求读取函数库的内容;但是从升级难易度来看明显没有优势,如果函数库更新,需要重新编译。
1.2 动态函数库动态函数库的扩展名⼀般为(.so或.dll),这类函数库通常名为libxxx.so或xxx.dll 。
与静态函数库被整个捕捉到程序中不同,动态函数库在编译的时候,在程序⾥只有⼀个“指向”的位置⽽已,也就是说当可执⾏⽂件需要使⽤到函数库的机制时,程序才会去读取函数库来使⽤;也就是说可执⾏⽂件⽆法单独运⾏。
这样从产品功能升级⾓度⽅便升级,只要替换对应动态库即可,不必重新编译整个可执⾏⽂件。
1.3总结从产品化的⾓度,发布的算法库或功能库尽量使动态库,这样⽅便更新和升级,不必重新编译整个可执⾏⽂件,只需新版本动态库替换掉旧动态库即可。
从函数库集成的⾓度,若要将发布的所有⼦库(不⽌⼀个)集成为⼀个动态库向外提供接⼝,那么就需要将所有⼦库编译为静态库,这样所有⼦库就可以全部编译进⽬标动态库中,由最终的⼀个集成库向外提供功能。
2.qmake⽅式⽣成和调⽤动态/静态库链接:https:///lywzgzl/article/details/428059912.1 ⽣成库QT -= guiTARGET = laser_libTEMPLATE = libCONFIG += staticlib #加这句是⽣成静态库,不加则是动态库DEFINES += LASER_LIB_LIBRARYDEFINES += QT_DEPRECATED_WARNINGSLIBS += /usr/lib/x86_64-linux-gnu/libboost_thread.so\/usr/lib/x86_64-linux-gnu/libboost_system.soSOURCES += \laser_lib.cppHEADERS += \laser_lib.h \laser_lib_global.hinclude(LMS1xx/LMS1xx.pri)DESTDIR = $$PWD/../Libunix {target.path = /usr/libINSTALLS += target}2.2 调⽤库QT -= guiCONFIG += c++11 consoleCONFIG -= app_bundleDEFINES += QT_DEPRECATED_WARNINGS#增加系统库的依赖LIBS +=/usr/lib/x86_64-linux-gnu/libboost_thread.so\/usr/lib/x86_64-linux-gnu/libboost_system.so#增加⾃定义库的依赖LIBS += -L$$PWD/../Lib -llaser_lib #$$PWD获取当前pro⽂件的⽬录INCLUDEPATH += ../laser_libSOURCES += main.cppDESTDIR = $$PWD/../Lib3.cmake⽅式⽣成和调⽤动态库3.1创建共享库项⽬Cmake新建⼀个Qt Creator项⽬,在CMakeLists.txt中添加如下代码#-------------------------------------- 搜索软件包 --------------------------------------find_package(Qt5Widgets REQUIRED)find_package(Qt5Network REQUIRED)set(CMAKE_AUTOMOC ON)#-------------------------------------- 包含头⽂件 --------------------------------------include_directories(${Qt5Widgets_INCLUDE_DIRS})include_directories(${Qt5Network_INCLUDE_DIRS})include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)#-------------------------------------- -添加项⽬- --------------------------------------FILE(GLOB_RECURSE HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.h*)FILE(GLOB_RECURSE SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.c*)add_library(${PROJECT_NAME} SHARED${HEADER_FILES}${SOURCE_FILES}) #STATIC or SHARED 对应静态库或者动态库target_link_libraries(${PROJECT_NAME}${Qt5Widgets_LIBRARIES}${Qt5Network_LIBRARIES})#-------------------------------------- -设置输出- --------------------------------------set(OUTPUT_LIB_DIR ${PROJECT_BINARY_DIR}/libCACHE PATH "Output directory for libraries")file(MAKE_DIRECTORY ${OUTPUT_LIB_DIR})file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/${PROJECT_NAME})set(LIBRARY_OUTPUT_PATH ${OUTPUT_LIB_DIR})#-------------------------------------- -安装项⽬- --------------------------------------install(TARGETS ${PROJECT_NAME}EXPORT ${PROJECT_NAME}LIBRARY DESTINATION ${LIBRARY_OUTPUT_PATH})按需编辑plugintest.h和plugintest.cpp,这个就是该共享库项⽬的plugintest类了,我加⼊了⼀个int sum(int input1, int input2);公共函数,内容为:int Plugintest::sum(int input1, int input2){std::cout<<"Hello World!"<<std::endl;int sum = input1+input2;return sum;}保存并编译项⽬吧,没问题的话会在plugintest-build/lib⽬录⾥⽣成libplugintest.so。
1.什么是静态连接库,什么是动态链接库静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都全部被直接包含在最终生成的EXE 文件中了。
但是若使用DLL,该DLL 不必被包含在最终EXE 文件中,EXE 文件执行时可以“动态”地引用和卸载这个与EXE 独立的DLL 文件。
静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。
静态链接库与静态链接库调用规则总体比较如下。
对于静态链接库(比较简单):首先,静态链接库的使用需要库的开发者提供生成库的.h头文件和.lib文件。
生成库的.h头文件中的声明格式如下:extern "C" 函数返回类型函数名(参数表);在调用程序的.cpp源代码文件中如下:#include "..\lib.h"#pragma comment(lib,"..\\debug\\libTest.lib")//指定与静态库一起链接第二,因为静态链接库是将全部指令都包含入调用程序生成的EXE文件中。
因此如果用的是静态链接库,那么也就不存在“导出某个函数提供给用户使用”的情况,要想用就得全要!要不就都别要!:)对于动态链接库:动态链接库的使用,根据不同的调用方法,需要提供不同的资源:1. 静态加载------程序静态编译的时候就静态导入dll,这样的话就需要提供给库使用者(C客户)如下文件:*.lib文件和.dll文件和*.h。
其有2个坏处:1 程序一开始运行就需要载入整个dll,无法载入程序就不能开始运行;2 由于载入的是整个dll,需要耗费资源较多其调用方法如下:#include "..\lib.h"#pragma comment(lib,"..\\debug\\libTest.lib")但是这种方式的话可以调用Class method.2.动态加载-----那么只需要提供dll文件。
因此调用程序若想调用DLL中的某个函数就要以某种形式或方式指明它到底想调用哪一个函数。
但是无法调用Class method了。
如果要调用Dll中的function,需要经历3个步骤:Handle h=LoadLibrary(dllName) --> GetProcAddress(h,functionName) 返回函数指针,通过函指针调用其function-->FreeLibrary(h)例如:Another.dll有一个int Add(int x,int y)函数。
则完整的调用过程如下:typedef int (* FunPtr)(int,int);//定义函数指针FunPtr funPtr;Handle h=LoadLibrary("Another.dll");funPtr=(FunPtr)GetProcAddress(h,"Add");funPtr(2,3);//2+3;FreeLibrary(h);2.示例示例之一:静态链接库的创建过程:例如:我们创建一个自定义字符串的类CHironString,只需要在IDE里面添加class即可,然后program相应函数体代码如下所示:SDLL.h文件------------------------------------------------------------------------// HironString.h: interface for the CHironString class.////////////////////////////////////////////////////////////////////////#if !defined(AFX_HIRONSTRING_H__B23C5E5E_0E8B_4030_B057_34A40 C934C59__INCLUDED_)#defineAFX_HIRONSTRING_H__B23C5E5E_0E8B_4030_B057_34A40C934C59__I NCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000class CHironString{private:char* m_data;public:char * GetData();CHironString(CHironString &other);int Length();CHironString();CHironString(char * str);CHironString& operator=(CHironString &other);virtual ~CHironString();};#endif// !defined(AFX_HIRONSTRING_H__B23C5E5E_0E8B_4030_B057_34A40C 934C59__INCLUDED_)SDLL.CPP如下:--------------------------------------------------------------// HironString.cpp: implementation of the CHironString class.////////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "HironString.h"//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////CHironString::CHironString(){m_data=NULL;}CHironString::CHironString(char * str){int len=strlen(str);m_data=new char[len+1];strcpy(m_data,str);}CHironString::~CHironString(){delete m_data;}int CHironString::Length(){return strlen(m_data);}CHironString::CHironString(CHironString &other){int len=strlen(other.m_data)+1;m_data=new char[len];strcpy(m_data,other.m_data);}CHironString& CHironString::operator =(CHironString &other){if(this==&other)return *this;if(m_data!=NULL)delete[] m_data;int len=strlen(other.m_data)+1;m_data=new char[len];strcpy(m_data,other.m_data);return *this;}char * CHironString::GetData(){return m_data;}然后,将程序编译后生成sdll.lib。
客户调用:将CHironString.h和SDLL.lib发布给client,那么客户端就可以调用我们编写的静态链接库了。
示例之二:动态链接库的创建首先我们必须先注意到DLL内的函数分为两种:(1)DLL 导出函数,可供应用程序调用;(2)DLL 内部函数,只能在DLL 程序使用,应用程序无法调用它们。
我们还是创建一个自定义的字符串处理类CHironString,不同之处其是一个动态链接库Dll。
动态链接库的export 需要在在相应的头文件中编写相应的MACROMyDll.h:自定义了一些类(函数)export 宏(该文件由IDE自动生成)如下------------------------------------------------------------------#ifdef MYDLL_EXPORTS#define MYDLL_API __declspec(dllexport)#else#define MYDLL_API __declspec(dllimport)#endif这是导出类的宏定义,将导出类必须加上该宏,才能被导出。
此处的MYDLL_EXPORTS会出现在project-->settings-->C/C++页面上的PreProcessor definition中,这个MACRO表明其要定义一个导出宏CHironString.h 自定义类头文件----------------------------------------------------------------// HironString.h: interface for the CHironString class.////////////////////////////////////////////////////////////////////////CHironString.Cpp------------------------------------------------------------// HironString.cpp: implementation of the CHironString class. //////////////////////////////////////////////////////////////////////// #include "stdafx.h"#include "HironString.h"////////////////////////////////////////////////////////////////////// // Construction/Destruction////////////////////////////////////////////////////////////////////// CHironString::CHironString(){m_data=NULL;}CHironString::CHironString(char * str){int len=strlen(str);m_data=new char[len+1];strcpy(m_data,str);}CHironString::~CHironString(){delete m_data;}int CHironString::Length(){return strlen(m_data);}CHironString::CHironString(CHironString &other){int len=strlen(other.m_data)+1;m_data=new char[len];strcpy(m_data,other.m_data);}CHironString& CHironString::operator =(CHironString &other) {if(this==&other)return *this;if(m_data!=NULL)delete[] m_data;int len=strlen(other.m_data)+1;m_data=new char[len];strcpy(m_data,other.m_data);return *this;}char * CHironString::GetData(){return m_data;}2.如果是动态加载,只需要提供*.dll即可经过compile之后,会生成MyDll.dll和MyDll.lib文件。