精华内容
下载资源
问答
  • 【Linux】修改动态链接库
    2022-03-04 13:25:31

    目录

    1、简介

    2、方法


    1、简介

    最近发现服务器根目录下有好多cuda版本,因为内存不足等原因需删除一些cuda,因此需要先将动态链接库转为之前的版本,而后删除相关文件

    2、方法

    刚开始文件存储

    df -hl

    先查看文件所在位置在/usr/local

    更多相关内容
  • 作为演示,我已将Windows移植Windows动态链接库移植到Linux简介此存储库包含一个库,该库允许本机Linux程序从Windows DLL加载和调用函数。 作为演示,我已将Windows Defender移植到Linux。 $ ./mpclient eicar....
  • PB调用wfZip动态链接库

    2018-09-17 13:40:44
    软件简介: 采用了标准的Dll组件方式,可供多种程序调用。 本组件支持将多个文件快速的压缩成一个zip压缩文件。 本组件支持将指定zip压缩文件解压缩到指定目录。 Delphi、PB、VB原码说明
  • C++ 动态链接库

    万次阅读 多人点赞 2021-06-01 09:01:19
    点击去这里寻找 C++ DLL简介以及使用 1>认识DLL(动态链接库) 2 >格式后缀 3 >DLL优点 4 >DLL缺点 5 >加载DLL 1>动态加载(运行时加载)通过LoadLibary加载, GetProcAddress调用。 2>静态加载方式(.h .lib .dll三件套...

    原创文章,转载请注明出处。

    如果Windows系统有缺失的DLL文件,可以去这个链接下载。点击去这里寻找

    1>认识DLL(动态链接库)

    动态链接库DLL(Dynamic-Link Library)通常包含程序员自定义的变量和函数, 可以在运行时动态链接到可执行文件(我们的exe程序)中。

    2 >格式后缀

    Windows上:(.dll)
    Linux上:(.so)
    Android上:(.so)
    IOS上:(.dylib)

    3 >DLL优点

    1)模块化,耦合小:大规模软件开发中,开发过程独立,耦合度小,比如UE4里面的模块(每一个.build.cs)都是一个DLL。

    2)扩展性:DLL文件与EXE文件是独立的,只要接口不变,升级程序只需更新DLL文件不需要重新编译应用程序。并且我们的EXE文件较小。

    3)复用性:DLL的编制与具体的编程语言以及编译器无关,不同语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数。

    4)节省内存:当应用程序使用动态链接时,多个应用程序可以共享磁盘上单个DLL副本。

    5)隐私性:可以当做黑盒使用,可以将我们的具体实现代码隐藏起来,比如我们想将算法的具体实现隐藏起来,不让别人看到我是怎么做的。一般SDK接入时候,里面的具体算法实现都是不会公开cpp的。

    4 >DLL缺点

    如果是动态loaddll的话,会牺牲部分性能吧。微乎其微的。

    5 >加载DLL

    1>动态加载(运行时加载)通过LoadLibary加载, GetProcAddress调用。

    如果加载失败,通过GetLastError()获取失败原因。

    下面是LoadLibary的示例代码
    第一步,在.h中声明了static HMODULE hDLL;

    #include<Windows.h> //加载的头文件
    
    class QIDCardReader : public QMainWindow
    {
        Q_OBJECT
    
    public:
        QIDCardReader(QWidget* parent = 0);
    private:
    	static HMODULE hDLL;
    };
    

    第二步,定义要调用的dll中的方法。并通过LoadLibrary给hDLL赋值

    #include "QIDCardReader.h"
    
    //CPP中预声明一下我要调用dll里面的方法
    typedef int(*MyRouton_RepeatRead)(bool);
    typedef int(*MyInitComm)(int);
    typedef int(*MyAuthenticate)();
    typedef int(*MyReadBaseInfosPhoto)(char * , char * , char * ,
    	char *, char * , char * ,
    	char *, char * , char* , char * );
    typedef int(*MyCloseComm)();
    
    HMODULE QIDCardReader::hDLL;
    
    QIDCardReader::QIDCardReader(QWidget* parent) : QMainWindow(parent)
    	,ui_(new Ui::QIDCardReaderClass)
    {
    	hDLL = LoadLibrary(L"D:\\bimvr-vrlauncher\\test\\Sdtapi.dll"); //加载dll文件 
    	//如果加载失败的话, 通过GetLastError()进行获取,看失败原因。
    	auto code5 = GetLastError();
    }
    

    第三步,调用dll中的方法 GetProcAddress(hDLL, “实际的dll端函数导出名称”)

    //调用1
    if (hDLL)
    {
    	MyRouton_RepeatRead MyRouton_RepeatReadFunc = (MyRouton_RepeatRead)GetProcAddress(hDLL, ("Routon_RepeatRead"));//直接使用原工程函数名 
    	if (MyRouton_RepeatReadFunc)
    	{
    		MyRouton_RepeatReadFunc(true);
    	}
    
    }
    
    //调用2
    int iPort = 1001;
    //int ret = InitComm(iPort);
    int ret = -1000;
    if (hDLL)
    {
    	MyInitComm MyInitCommFunc = (MyInitComm)GetProcAddress(hDLL, ("InitComm"));//直接使用原工程函数名 
    	if (MyInitCommFunc)
    	{
    		ret = MyInitCommFunc(iPort);
    	}
    }
    if (ret)
    {
    	//ret = Authenticate();
    	if (hDLL)
    	{
    		MyAuthenticate MyAuthenticateFunc = (MyAuthenticate)GetProcAddress(hDLL, ("Authenticate"));//直接使用原工程函数名 
    		if (MyAuthenticateFunc)
    		{
    			ret = MyAuthenticateFunc();
    		}
    	}
    	if (ret)
    	{
    		char user_name[31] = { 0 };
    		char user_gender[3] = { 0 };
    		char user_folk[11] = { 0 };
    		char user_birthday[9] = { 0 };
    		char user_code[19] = { 0 };
    		char user_address[71] = { 0 };
    		char user_agency[31] = { 0 };
    		char expire_start[9] = { 0 };
    		char expire_end[9] = { 0 };
    
    		QByteArray data_path = QString::fromStdWString(AppUtils::GetDataPath()).toLatin1();
    		ret = ReadBaseInfosPhoto(user_name, user_gender, user_folk, user_birthday, user_code,
    			user_address, user_agency, expire_start, expire_end, str/*data_path.data()*/);
    		if (hDLL)
    		{
    			MyReadBaseInfosPhoto MyReadBaseInfosPhotoFunc = (MyReadBaseInfosPhoto)GetProcAddress(hDLL, ("ReadBaseInfosPhoto"));//直接使用原工程函数名 
    			if (MyReadBaseInfosPhotoFunc)
    			{
    				ret = MyReadBaseInfosPhotoFunc(user_name, user_gender, user_folk, user_birthday, user_code,
    						user_address, user_agency, expire_start, expire_end, str/*data_path.data()*/);
    			}
    		}
    	}
    }
    

    第四步,可以选择性调用FreeLibrary(hDLL)卸载Dll,这个是下面的静态三件套加载方式做不到的。
    也就是说我们可以动态控制Dll的加载与卸载。

    2>静态加载方式(.h .lib .dll三件套加载)

    1>项目->属性->配置属性->VC++ 目录-> 在“包含目录”里添加头文件Sdtapi.h所在的目录
    2>项目->属性->配置属性->VC++ 目录-> 在“库目录”里添加头文件Sdtapi.lib所在的目录
    3>项目->属性->配置属性->链接器->输入-> 在“附加依赖项”里添加“Sdtapi.lib”(若有多个 lib 则以空格隔开)
    也可以使用#pragma comment(lib, “Sdtapi.lib”)代替上面的1、2、3步骤。

    在这里插入图片描述
    QIDCardReader.cpp 包含.h,将.h添加到项目中

    #include "sdtapi.h"
    
    void QIDCardReader::onNotify()
    {
    	Routon_RepeatRead(true);
    
    	int iPort = 1001;
    	int ret = InitComm(iPort);
    	if (ret)
    	{
    		ret = Authenticate();
    		if (ret)
    		{
    			char user_name[31] = {0};
    			char user_gender[3] = {0};
    			char user_folk[11] = {0};
    			char user_birthday[9] = {0};
    			char user_code[19] = {0};
    			char user_address[71] = {0};
    			char user_agency[31] = {0};
    			char expire_start[9] = {0};
    			char expire_end[9] = {0};
    
    			QByteArray data_path = QString::fromStdWString(AppUtils::GetDataPath()).toLatin1();
    			ret = ReadBaseInfosPhoto(user_name, user_gender, user_folk, user_birthday, user_code,
    				user_address, user_agency, expire_start, expire_end, data_path.data());
    		}
    	}
    }
    

    现在是可以通过编译了,但是运行会报错 提示LinkError
    因为程序分为编译和链接两步骤,这就是为什么报错误的原因。
    我们解决这个报错就是将.dll放到和.exe同级目录就好了

    如果最终exe找不到dll的话,会提示下面的错误。解决方法就是将dll放到和exe同级目录就好了。
    在这里插入图片描述
    谢谢,创作不易,大侠请留步… 动起可爱的双手,来个赞再走呗 <( ̄︶ ̄)>

    展开全文
  • 台达PLC DVP读写动态链接库简介: 项目中用到的台达PLC DVP一个啥型号时,需要读取XY是写的。 网上下载的,没找到能使用的。所以干脆自己学习台达那个PLC通信协议1.1版,自己动手写了。 新手一般使用应该是够了。...
  • Windows动态链接库

    千次阅读 2020-03-10 19:44:08
    一、Windows的动态链接库简介 DLL即动态链接库(Dynamic-Link Library)的缩写,相当于Linux下的共享对象。Windows系统中大量采用DLL机制,甚至内核的结构很大程度依赖于DLL机制。Windows下的DLL文件和EXE文件实际上...

    一、Windows的动态链接库简介

    DLL即动态链接库(Dynamic-Link Library)的缩写,相当于Linux下的共享对象。Windows系统中大量采用DLL机制,甚至内核的结构很大程度依赖于DLL机制。Windows下的DLL文件和EXE文件实际上是一个概念,都是PE格式的二进制文件。

    1.1 Windows下面的动态链接库与Linux下面的动态链接库的区别

    (1)文件后缀不同

    Linux动态库的后缀是 .so 文件,而window则是 .dll 文件

    (2)文件格式不同

    (a)Linux下是ELF格式,即Executable and Linkable Format。在ELF之下,共享库中所有的全局函数和变量在默认情况下都可以被其它模块使用,即ELF默认导出所有的全局符号。

    (b)Windows下面是PE格式的文件,即Portable Executable Format。DLL本质上也是PE文件,DLL需要显示地“告诉”编译器需要导出某个符号,否则编译器默认所有的符号都不导出。

    (c)动态链接库的文件个数不一样

    Linux的动态链接库就只有一个 .so 文件,还有与之对应的头文件,而在Windows下面的动态库有两个文件,一个是引入库(.LIB)文件,一个是动态库(.DLL)文件,需要的头文件(.h)文件。

    (1)引入库文件包含被DLL导出的函数的名称和位置,对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。

    (2)DLL文件包含实际的函数和数据,应用程序使用LIB文件链接到所需要使用的DLL文件,库中的函数和数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码链接起来,从而节省了内存资源。

    总结:从上面的说明可以看出,Windows下面所创建的动态链接库DLL和.LIB文件必须随应用程序一起发行,否则应用程序将会产生错误。一般的动态库程序有lib文件和dll文件,lib文件是编译时期连接到应用程序中的,而dll文件才是运行时才会被调用的。

    1.2 静态链接库和动态链接库的异同点

    如果采用静态链链接库(.lib),lib中的指令最终都会编译到链接该静态库的exe(或dll)文件中,发布软件时,只需要发布exe(或dll)文件,不需要.lib文件。

    但是若使用动态链接库(. dll),dll中的指令不会编译到exe文件中,而是在exe文件执行期间,动态的加载和卸载独立的dll文件,需要和exe文件一起发布。

    静态链接库不能再包含其他动态链接库或静态链接库,而动态链接库不受此限制,动态链接库中可以再包含其他的动态链接库和静态链接库。

    来自:https://blog.csdn.net/w_y2010/article/details/80428067

    1.3 动态链接库的优点

    1)节省内存和代码重用:当应用程序使用动态链接时,多个应用程序可以共享磁盘上单个DLL副本

    2)可扩展性:DLL文件与EXE文件独立,只要接口不变,升级程序只需更新DLL文件不需要重新编译应用程序

    3)复用性:DLL的编制与具体的编程语言以及编译器无关,不同语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数1

    1.4 有下面的代码

    • 头文件framework.h
    #pragma once
    namespace mycal
    {
    	int add(int a, int b);
    
    	int sub(int a, int b);
    }
    
    • 实现代码 framework.cpp
    //framework.cpp
    #include "framework.h"
    
    int mycal::add(int x, int y)
    {
    	return x + y;
    }
    
    int mycal::sub(int x, int y)
    {
    	return x - y;
    }
    

    在Linux下,编译成动态链接库之后,会得到一个 xxx.so 文件,现在只要引入头文件,包含动态库路径,就可以正常使用了,但是上面的代码同样在Windows下面,使用VS2017编译成动态链接库之后,的确不会报错,只会的到一个 xxx.dll 文件,(不是还有一个对应的 xxx.lib文件吗,哪里去了呢?)

    然后我们新建一个项目,按照 “头文件路径配置——库文件路径配置”的方法,编写代码,我们也可以调用到add这两个函数,还有语法提示,因为语法提示其实来自于头文件,和库文件没关系,但是编译却不成功了,显示调用的add以及sub都是错误的,这是为什么呢?

    这是因为前面说了Windows下面需要显式的告诉编译器,动态库中有哪一些函数是可以导出使用的,上面没有显示说明,即add和sub实际上是不可以使用的,故而会报错,怎么办呢?参见下面。

    二、Windows平台之下使用VS2017如何创建动态库

    2.1 解决未生成lib文件以及函数没有显式导出的问题

    两种方式来决定动态库中到底哪些函数是可以导出供外部直接使用的,以及与此同时生成与dll对应的 .lib 文件。

    (1)MSVC编译器提供了关键字_declspec,来指定指定符号的导入导出,即_declspec属性关键字

    _declspec(dllexport) 表示该符号是从本DLL导出的符号:这是在定义DLL中的函数等源代码是必须使用的,如果不显式的导出某一些符号,则使用动态链接库虽然没有语法上的错误,但是她无法编译,因为dll中的函数没有暴露出来,故而找不到。

    _declspec(dllimport)表示该符号是从别的DLL中导入的:我们在使用动态链接库DLL中暴露出来的函数的时候,可以直接使用暴露的函数,也可以通过显示地导入函数,编译器会产生质量更好的代码。由于编译器确切地知道了一个函数是否在一个DLL中,它就可以产生更好的代码,不再需要间接的调用转接。如下所示:

    //显式的导入dll中暴露出来的函数
    __declspec(dllimport) void func1(void);
    int main(void)
    {
    	func1();
    }
    

    后面会专门讲如何使用 __declspec 来创建动态库。

    (2)使用"xxx.def"文件来声明导入和导出符号

    我们也可以不使用__declspec 来创建动态库,我们就按照正常的程序编写,如第一章节里面的 myMath.h 和 myMath.cpp 里面的内容,然后显示的添加一个 xxx.def 文件,怎么添加呢?

    如下:右击项目/添加/新建项,选择如下的文件:
    在这里插入图片描述
    默认是使用source.def 我们可以自定义名称。关于这个def文件是如何规定哪些内容是导出的,哪一些是不导出的,这里暂时先不说明了,可以参考下面的几篇文章:

    https://blog.csdn.net/qwq1503/article/details/85696279

    http://www.cnblogs.com/enterBeijingThreetimes/archive/2010/08/04/1792099.html

    2.2 使用 __declspec 来创建动态库的完整过程

    (1)新建一个空项目或者是使用DLL模板都可以。

    • 添加头文件 framework.h
    //framework.h
    #pragma once
    
    #define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
    // Windows Header Files
    #include <windows.h>
    
    namespace mycal {
    	__declspec(dllexport) int add(int a, int b);
    	__declspec(dllexport) int sub(int a, int b);
    }
    

    注意:实际上就是在需要定义的函数前面添加一个 __declspec(dllexport) 是两个短下划线开头哦!来表示这两个函数是暴露出来可以供直接使用的,没有暴露的函数,在动态链接库中是没办法使用的。

    2)实现函数的内容。

    • 定义一个 framework.cpp文件
    //framework.cpp
    #include "framework.h"
    
    int mycal::add(int x, int y)
    {
    	return x + y;
    }
    
    int mycal::sub(int x, int y)
    {
    	return x - y;
    }
    

    这个地方和我们平时的实现完全一样,实现的时候不再需要添加 __declspec(dllexport) 了。

    (3)生成项目

    比如我选择生成 Debug x64位的结果,

    生成之后得到如下的结果:
    在这里插入图片描述
    我们发现有一对配套的 xxx.dll 和 xxx.lib 文件,他们的大小不一样哦!此lib文件只是dll文件中导出函数的声明和定位信息,并不包含函数的实现,因此此lib文件只是在调用对应dll库的工程编译时使用,不需要随exe发布。

    三、动态链接库的使用

    3.1 静态调用dll

    静态调用是由编译系统完成对dll文件的加载和应用程序结束时完成对dll的卸载,当调用某dll的应用程序结束时,则windows系统对该dll的应用记录减1,直到使用该dll的所有应用程序都结束,即对该dll应用记录为0,操作系统会卸载该dll,静态调用方法简单,但不如动态调用适用。

    前面说了,window上生成的动态链接库的使用需要三个东西:头文件,dll文件,与dll对应的lib文件。

    这里都具备了,现在新建一个项目,如何配置呢?

    三步走配置

    (1)第一步:配置包含路径——即头文件所在的路径,将头文件复制过来。
    在这里插入图片描述

    (2)第二步:配置库路径——即lib所在的路径,将Dll_demo_1.lib也复制到当前工程文件夹中。
    在这里插入图片描述

    (3)第三步:添加链接,——将上面得到的Dll_demo_1.lib添加到链接器:

    #pragma comment(lib,"Dll_demo_1.lib")
    

    这一句是告诉编译器与该dll相对应的.lib文件所在的路径和文件名。在生成dll文件时,链接器会自动为其生成一个对应的.lib文件,该文件包含了dll导出函数的符号名和序号(并没有实际的代码)。在应用程序中,.lib文件将作为dll的替代文件参与编译,编译完成后,.lib文件就不需要了。

    修改复制过来的 framework.h,将里面的__declspec(dllexport)为__declspec(dllimport):

    #pragma once
    #define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
    // Windows Header Files
    #include <windows.h>
    
    namespace mycal {
    	__declspec(dllimport) int add(int a, int b);
    	__declspec(dllimport) int sub(int a, int b);
    }
    

    Source.cpp 代码如下:

    #include <iostream>
    #include <myMath.h> //添加自己定义的头
    #pragma comment(lib,"Dll_demo_1.lib")
    int main()
    {
    	int x = 50;
    	int y = 10;
    	int a,b;
    	a = mycal::add(x, y);
    	b = mycal::sub(x, y);
    	printf("%d %d\n", a, b);
    	getchar();
    	return 0;
    }
    

    现在生成,生成没有错误,但是运行依然会报错,因为运行的时候需动态链接库,所以还需要配置动态链接库。

    一共有三种方式,本文采用最简单的方式,直接将动态链接库和可执行exe文件拷贝到一起即可。
    在这里插入图片描述
    然后运行上面的程序,得到结果如下:

    120 80
    上面就是整个动态链接库的创建以及使用的过程。

    注意1

    1)可以修改.lib文件的文件名,只要在项目引用它时,使用它目前的名称,便可以正确运行,但不能改变.dll文件的名字,不然也会出现找不到.dll文件的错误

    2).dll文件必须和.exe放在一起,.exe文件在哪里.dll文件也得在那里,两者“共存亡”,否则就会出现找不到.dll文件的错误

    3)和静态库一样,.dll文件也要和应用程序的位数相对应,要么都是64位的,要么都是32位的,不可交叉使用。

    4)静态调用不需要使用Win32API函数来加载和卸载Dll以及获取Dll中导出函数的地址,这是因为当通过静态链接方式编译生成程序时,编译器会将.lib文件中导出函数的函数符号链接到生成的exe文件中,.lib文件中包含的与之对应的dll文件的文件名也被编译存储在exe文件内部,当应用程序运行过程中需要加载dll文件时,windows将根据这些信息查找并加载dll,然后通过符号名实现对dll函数的动态链接,这样,exe将能直接通过函数名调用dll 的输出函数,就像调用程序内部的其他函数一样。

    3.2 动态调用dll

    动态调用是由程序员调用系统API函数加载和卸载dll,程序员可以决定dll文件何时加载,何时卸载,加载哪个dll文件,将dll文件的使用权完全交给程序员。

    1)、新建控制台项目,添加 main.cpp 文件,将刚刚生成的 Dll_demo_1.dll 文件拷贝到项目目录下,main.cpp 代码如下

    #include "stdio.h"
    #include <windows.h>
    
    typedef int (*lpAddFun)(int ,int );//宏定义函数指针类型
    
    int main()
    {
    	HINSTANCE hDll;//DLL 句柄
    	lpAddFun addFun;//函数指针
    	hDll = LoadLibrary(L"Dll_demo_1.dll");//动态获取dll文件的路径
    	if (hDll!=NULL)
    	{
    		addFun =(lpAddFun)GetProcAddress(hDll,"add");//根据函数名在dll文件中获取该函数的地址	
    		if (addFun!=NULL)
    		{
    			int result =addFun(2,3);
    			printf("2+3=%d",result);
    		}
    
    	FreeLibrary(hDll);
    	}
    	return 0;
    }
    

    运行结果:2+3=5

    3.2.1 main.cpp分析

    语句typedef int (*lpAddFun)(int ,int )定义了一个与add函数接收参数类型和返回值均相同的函数指针类型,随后在main函数中定义了lpAddFun的实例addFun;在函数main中定义了一个DLL HISTANCE句柄实例hDll,通过Win32API函数LoadLibrary动态加载DLL模块并将DLL模块句柄赋给hDll
    main函数中通过Win32API函数GetProcAddress得到所加载的DLL模块中函数add的地址并赋值给addFun,经由函数指针addFun进行了对该DLLadd函数的调用;
    在完成对dll的调用后,在main函数中通过Win32API函数FreeLibrary释放已加载的DLL模块。

    通过以上的分析可知:
    (a) 动态调用只需要dll文件即可,不需要对应的.h头文件和.lib文件,一般情况下,只要有dll,就可以调用此dll中的导出函数。
    (b) 在调用dll中的函数时,需要知道导出函数的函数签名,若拥有dll对应的头文件,可以参照头文件即可,若没有头文件,使用特定工具也可以得到dll中导出函数的函数签名
    (c) DLL需要已某种特定的方式声明导出函数。
    (d) 应用程序需要以特定的方式调用DLL的淡出函数。

    四、Visual Studio提供了一个命令行工具:Dumpbin

    这个工具不需要自己安装,我们通过安装VS,可以直接使用,如下打开VS自带的命令行工具,如下:
    在这里插入图片描述
    这个工具有什么作用呢?简而言之,它可以查看一个 lib文件 dll文件提供了哪一些函数,暴露出来可供使用的,它还可以查看 exe 文件包含了哪一些静态库和动态库。

    查看一下它的帮助信息:
    在这里插入图片描述

    如何使用呢?举几个简单的例子,以本文所创建的动态库和可执行程序作为演示:

    (1)查看Dll_demo_1.dll 暴露出来了哪一些函数可以使用——dumpbin -exports xxxx.dll(xxxx.lib文件也一样的)

    F:\OpenCV4.1.1_Test\2020_01_10\calcuDll\calculate\x64\Release>dumpbin -exports calculate.dll

    总结:

    查看导入:dumpbin -exports 文件名称

    查看导出:dumpbin -imports 文件名称


    1. https://blog.csdn.net/qq_33757398/article/details/81545966 ↩︎ ↩︎

    展开全文
  • 动态链接库运算器

    2012-12-10 21:48:54
    在应用程序中用 LoadLibrary或MFC提供的AfxLoadLibrary显式的将自己所做的动态链接库调进来,动态链接库的文件名即是上述两个函数的参数,此后再用GetProcAddress()获取想要引入的函数。自此,你就可以象使用如同在...
  • 可以说,学习C/C++开发的人掌握动态链接库和静态链接库的制作与使用,可谓是最基本的技能了。

    文档声明:
    以下资料均属于本人在学习过程中产出的学习笔记,如果错误或者遗漏之处,请多多指正。并且该文档在后期会随着学习的深入不断补充完善。感谢各位的参考查看。


    笔记资料仅供学习交流使用,转载请标明出处,谢谢配合。
    如果存在相关知识点的遗漏,可以在评论区留言,看到后将在第一时间更新。
    作者:Aliven888

    1、开发环境

    系统:win7 x64 旗舰版
    编译器: Visual Studio 2015
    编译环境:Debug x86

    2、简介

      可以说,学习C/C++开发的人掌握动态链接库和静态链接库的制作与使用,可谓是最基本的技能了。

    静态库和动态库:
    静态库:包含函数代码本身,在编译时直接将代码加入程序当中,称为静态链接库static link library。函数和数据被编译进一个二进制文件(扩展名通常为.lib),在使用静态库的情况下,在编译链接可执行文件时,链接器从静态库中复制这些函数和数据,并把它们和应用程序的其他模块组合起来创建最终的可执行文件(.exe)。当发布产品时,只需要发布这个可执行文件,并不需要发布被使用的静态库。

    动态库:包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library。在使用动态库时,往往提供两个文件:一个引入库(.lib,非必须)和一个.dll文件。这里的引入库和静态库文件虽然扩展名都是.lib,但是有着本质上的区别,对于一个动态链接库来说,其引入库文件包含该动态库导出的函数和变量的符号名,而.dll文件包含该动态库实际的函数和数据。

    本章节只会介绍动态链接库的制作与使用;其中需要注意的是,动态链接库的制作有 使用 __declspec(dllexport) 创建dll使用模块定义(.def)文件创建dll 两种方式,这里我们先重点介绍第一种,因为第一种方式使用起来更加的方便和灵活。

    使用动态链接库的好处:

    • 可以使用多种编程语言编写:比如我们可以用VC++编写dll,然后在VB编写的程序中调用它。
    • 增强产品功能:可以通过开发新的dll取代产品原有的dll,达到增强产品性能的目的。比如我们看到很多产品改动了界面插件功能,允许用户动态地更换程序的界面,这就可以通过更换界面dll来实现。
    • 提供二次开发的平台:用户可以单独利用dll调用其中实现的功能,来完成其他应用,实现二次开发。
    • 节省内存:如果多个应用程序使用同一个dll,该dll的页面只需要存入内存一次,所有的应用程序都可以共享它的页面,从而节省内存。

    3、相关知识介绍

    在开始制作动态链接库之前,我们先了解一些与之有关的知识。

    dllexport类: 声明类dllexport时,将导出其所有成员函数和静态数据成员。您必须在同一程序中提供所有此类成员的定义。否则,将生成链接器错误。此规则的一个例外适用于纯虚函数,您无需为其提供显式定义。但是,因为抽象类的析构函数总是由基类的析构函数调用,所以纯虚拟析构函数必须始终提供定义。请注意,这些规则对于不可导出的类是相同的。如果导出类类型的数据或返回类的函数,请确保导出该类。

    dllimport类 声明类dllimport时,将导入其所有成员函数和静态数据成员。与dllimport和dllexport在非类类型上的行为不同,静态数据成员不能在定义dllimport类的同一程序中指定定义。

    4、制作一个动态链接库

    第一步:创建一个dll项目工程:
    在这里插入图片描述

    在这里插入图片描述

    第二步:在项目工程中添加一个 .cpp 文件和 .h文件(名称可以根据自己的需求去定义)。

    在这里插入图片描述

    第三步:再两个文件中,分别写入如下代码:

    //Alivendll.cpp
    #include "Alivendll.h"
    
    void AlivenTest()
    {
    	cout << "This is a dll test ." << endl;
    }
    
    
    //Alivendll.h
    #pragma once
    #include <iostream>
    using namespace std;
    
    #ifdef ALIVENDLL_EXPORTS  //该宏是项目自定义的
    #define ALIVEN_API extern "C" __declspec(dllexport)
    #else
    #define ALIVEN_API extern "C" __declspec(dllimport)
    #endif //ALIVENDLL_EXPORTS
    
    ALIVEN_API void AlivenTest();
    
    
    

    在这里插入图片描述

    第四步:选择好编译环境后(这里我测试的环境的是 Debug x86),编译项目即可。最终我们可以获取到 Alivendll.dll 和 Alivendll.lib 文件。

    在这里插入图片描述
    在这里插入图片描述

    5、使用动态链接库

    第一步:创建一个项目工程,这里选择控制台应用程序。

    在这里插入图片描述

    在这里插入图片描述

    调用动态链接库需要三个文件(.dll、.lib、*.h)如下图示;接下来我们详细讲解下调用过程:

    在这里插入图片描述
    第二步:将Alivendll.h放在应用程序的目录下(一般建议放到应用程序目录下,但是也可以放到其他目录下),并导入到应用程序中。

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    第三步:将Alivendll.lib放在应用程序的目录下(一般建议放到应用程序目录下,但是也可以放到其他目录下),并导入到应用程序中。

    这里需要注意下,Alivendll.lib 的导入有三种方式:
    第一种:#pragma comment(lib, “Alivendll.lib”)
    第二种:在属性中配置附加依赖项
    第三种,直接加载到项目中。

    详细操作可以参见《C/C++ 静态链接库(lib)的三种常用调用方式》这篇博客。

    在这里插入图片描述
    第四步:将Alivendll.dll放在应用程序的可执行文件(exe)目录下。

    在这里插入图片描述

    笔记跟新记录

    时间内容
    2020-11-04创建笔记
    2020-11-08优化文章格式以及修改部分错别字
    展开全文
  • 动态链接库简介

    千次阅读 2007-07-25 13:44:00
    动态链接库简介自从微软推出16位的Windows操作系统起,此后每种版本的Windows操作系统都非常依赖于动态链接库(DLL)中的函数和数据,实际上Windows操作系统中几乎所有的内容都由DLL以一种或另外一种形式代表着,例如...
  • C++_编写动态链接库

    千次阅读 2018-05-25 14:28:27
    动态链接库简介动态链接库(Dynamic Link Library 或者 Dynamic-link Library,缩写为 DLL),是微软公司在微软Windows操作系统中,实现共享函数库概念的一种方式。这些库函数的扩展名是 ”.dll”、”.ocx”(包含...
  • C/C++动态链接库(DLL)详解

    千次阅读 多人点赞 2018-09-30 23:22:55
    1. 动态链接库(dll)简介 2. 动态库和静态库区别 3. 使用动态链接库(dll)的好处 4. 内存页面 5. 动态链接库被多个进程访问 6. 动态链接库加载的两种方式 7. 如何查看动态链接库(dll)导出哪些函数 8. 创建动态...
  • 动态链接库(dll)简介

    千次阅读 2018-09-30 23:27:49
    1. 从微软推出第一个版本的Windows操作系统以来,动态链接库(DLL)一直是Windows操作系统的基础。 2. 动态链接库通常都不能直接运行,也不能接收消息。 它们是一些独立的文件,其中包含能被可执行程序或其它DLL...
  • 一、简介 为了提高代码的复用性,引入了是一段可执行代码的二进制...可以看到是在链接过程和目标文件一起打包最终生成可执行文件,另外可以看到静态动态库是编译型语言所特有的,对于非编译型语言例如p...
  • 一、链接库简介 之前已经写过一篇Linux环境下的静态与动态链接库对比和应用的文章:C++静态库与动态库—Linux基础篇。这里不再赘述,主要介绍Windows环境下与Linux的区别。 二、Windows静态库的创建和使用 2.1 ...
  • 前言:C以及C++的动态链接库和静态链接库,说起来很简单,但是实际上在创建的过程中有很多的坑,本人也是一路踩了很多坑,查了很多资料,下决定写一篇完整的文章来详细解释使用VS创建C++动态链接库的完整流程。...
  • 使用python创建生成动态链接库dll

    千次阅读 2020-12-22 01:50:53
    如今,随着深度学习的发展,python已经...动态链接库(.dll,.so)是系统开发中一种非常重要的跨语言协作方式。把python语言写成的算法编译成动态库,能够提供给其他语言调用,这能够在很大程度上提高算法的开发效率...
  • 再谈Android动态链接库

    千次阅读 2017-06-07 09:37:18
    其实这是一个常识问题,针对不同的架构我们肯定要提供不同的动态链接库,所以,在实际开发过程中,我们并不是将这7种so库都集成到我们的项目中去,我们会根据实际情况做一个取舍。那么旧事重提,我们再来看看And
  • 动态链接库dll的两种加载方式

    万次阅读 2018-01-22 00:17:26
    在第一篇技术博客"动态链接库简介"中说到了两种加载方式,当时没有详细说明,这里详细说明一下 可以通过两种方式  1.隐式链接(需要.dll,.lib,.h)  2.显式链接(需要.dll,.h) 方法1:隐式链接----需要.lib,.dll,.h...
  • 动态链接库(DLL)简介

    2008-12-14 20:25:57
    介绍了动态链接库编程的基本知识,并有源代码可以下载。是DLL程序入门的好帮手。
  • 动态链接库的隐式和显式加载1 前言2 隐式链接----需要.lib,.dll,.h文件2.1 第一种方式(对应上面每种搜索路径1):针对数量较少的库2.2 第二种方式(对应上面每种搜索路径2):针对数量比较多的库(Opencv)3 显式链接--...
  • Linux下编译动态链接库与使用详解

    千次阅读 2016-08-12 15:55:03
    linux下简介两种 静态 动态库 区别:在于代码被载入的时刻不同。静态的代码在编译过程中已经被载入可执行程序,因此体积较大。共享的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用...
  • Linux下动态链接库的创建和使用

    千次阅读 2016-04-06 13:40:41
    Linux链接库的创建和使用 链接库 动态链接库的创建和使用 静态链接库的创建和使用
  • vs2010创建和调用动态链接库和静态链接库
  • 原文地址:https://blog.csdn.net/github_37157365/article/details/79653292场景: 很多时候我们写代码的时候会经常用到某些代码段,比方...所以,可以自己动手写一个自己的动态链接库,保存起来。下次用到只需要...
  • Kunpeng是一个Golang编写的开源POC检测框架,集成了包括数据库,中间件,web组件,cms等的漏洞POC(),可检测弱密码,SQL注入,XSS,RCE等漏洞类型,以动态链接库的形式提供调用,通过此项目可快速开发突破检测类的...
  • Linux下的动态链接库.so文件的使用

    千次阅读 2021-05-09 07:12:30
    1 简介大家都知道,在WINDOWS系统中有很多的动态链接库(以.DLL为后缀的文件,DLL即Dynamic Link Library)。这种动态链接库,和静态函数库不同,它里面的函数并不是执行程序本身的一部分,而是根据执行程序需要按需...
  • 一、动态链接库简介 动态链接库英文为DLL,是Dynamic Link Library 的缩写形式,DLL是一个包含可由多个程序同时使用的代码和数据的库 ,DLL不是可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可...
  •  动态库的使用方式中有两种,第一种是类似于静态库的使用,另一种我称之为真正的动态加载动态库,主要是因为这种方式在程序运行的过程中加载链接库,使用之后在卸载链接库。  先介绍第一种。  在目录/home/owner/...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 53,449
精华内容 21,379
关键字:

动态链接库简介

友情链接: gjcdqwgy.zip