在某项目中,需要使用两个不同版本的HCNetSDK库,我们通常使用的静态加载DLL的方式不能满足该需求,故用到动态加载DLL的方式。
静态加载:也称隐式调用,指在运行程序之前由操作系统的加载器将DLL和EXE一起加载到内存里。注意这里与程序的静态链接区别开来,静态链接发生在编译过程之中,而DLL的静态加载是发生在程序运行之前。
动态加载:也称显示调用,指应用程序运行过程中程序自己完成对DLL的加载和卸载(DLL加载—DLL函数地址获取—DLL释放),应用程序在执行过程中随时可以加载DLL文件,也可以随时卸载DLL文件。
-
静态加载
DLL
静态加载DLL需要提供.h、.lib、.dll文件,假设需要加载的DLL文件名为MyDll.dll,静态加载DLL步骤如下:
(1)将MyDll.dll拷到目标工程(需调用MyDll.dll的工程)的Debug目录下;
(2)将MyDll.lib拷到目标工程(需调用MyDll.dll的工程)目录下;
(3)将MyDll.h(包含输出函数的定义)拷到目标工程(需调用MyDll.dll的工程)目录下;
(4)打开目标工程,选中目标工程名点击右键,依次选择【属性】-【配置属性】-【链接器】-【输入】,在附加依赖项中输入:MyDll.lib;
(5)在目标工程Head Files加入MyDll.h文件;
(6)在目标工程(*.cpp,需要调用MyDll.dll中的接口)中包含头文件,即#include “MyDll.h”,然后在该*.cpp中可直接调用MyDll.h中的接口。
-
动态加载
DLL
动态加载DLL不需要依赖.h和.lib文件,仅需要将.dll文件拷贝到应用程序所在目录下。
动态加载需主要用到LoadLibrary(加载DLL)、GetProcAddress(获得DLL中API函数的地址)、FreeLibrary(释放DLL)这几个系统函数。
LoadLibrary() 函数作用是将指定的可执行模块映射到调用进程的地址空间,如果调用成功, LoadLibrary() 函数将返回所加载的那个模块的句柄。当获取到动态链接库模块的句柄后,接下来就要想办法获取DLL导出函数的地址,这可以通过调用 GetProcAddress() 函数来实现。当DLL文件中的函数不再使用或程序结束时,需要使用FreeLibrary()函数对其进行释放。具体使用示例如下:
加载DLL:
#include <windows.h>
HINSTANCE hDllInst = LoadLibrary(“MyDll.dll”);
调用DLL中函数:
typedef BOOL (CALLBACK * pwmNET_DVR_Logout_V30)(long lUserID);
BOOL CLASSNAME::NET_DVR_Logout_V30(long lUserID)
pwmNET_DVR_Logout_V30 pNET_DVR_Logout_V30 = (pwmNET_DVR_Logout_V30)GetProcAddress(hDllInst, " NET_DVR_Logout_V30");
if (NULL == pNET_DVR_Logout_V30)
PAG_ERROR(">>> GetProcAddress [NET_DVR_Logout_V30] Failed!");
return FALSE;
return pNET_DVR_Logout_V30(lUserID);
释放DLL:
if(hDllInst!= NULL)
FreeLibrary(hDllInst);
-
静态加载与动态加载区别
(1)加载时间:静态加载发生在程序运行之前,故如果缺少dll文件,程序运行不起来。动态加载发生在程序运行过程中(由编程者决定何时加载),不会因为缺少dll,导致整个程序运行不起来。如果程序体积较大,功能较为复杂,静态加载会导致程序启动时间长。而动态加载可将较大的程序分开加载的,程序运行时只需要将主程序载入内存,程序启动快。
(2)依赖文件:静态加载需要.lib和.dll文件,动态加载只需要.dll文件。
(3)占用内存: 静态加载占用内存较大。静态加载可以在需要的时候用LoadLibrary进行加载,在不需要的时候用FreeLibrary进行卸载,这样可以不必占用内存。
(4)使用情况:静态加载使用简单方便。动态加载使用复杂一些,需要显示获取函数地址。
(1)介绍了DLL库静态加载和动态加载的方法及其区别。
(2) 加深了对DLL库静态加载和动态加载的理解,便于以后项目开发中选择合适的加载方式。
案例简述在某项目中,需要使用两个不同版本的HCNetSDK库,我们通常使用的静态加载DLL的方式不能满足该需求,故用到动态加载DLL的方式。背景技术及术语解释静态加载:也称隐式调用,指在运行程序之前由操作系统的加载器将DLL和EXE一起加载到内存里。注意这里与程序的静态链接区别开来,静态链接发生在编译过程之中,而DLL的静态加载是发生在程序运行之前。动态加载:也称显示调用,指应用程序运行过程中程序自己完成对DLL的加载和卸载(DLL加载—DLL函数地址获取—DLL释放),应用程序在执行过程...
// 下列 ifdef 块是创建使从
DLL
导出更简单的
// 宏的标准方法。此
DLL
中的所有文件都是用命令行上定义的 MY
DLL
_EXPORTS
// 符号编译的。在使用此
DLL
的
// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
头文件.h
extern "C" _declspec(
dll
export) int Max(int a, int b); //extern "C"解决函数名由于不同编译器造成的名字匹配问题,通常c++编译器编译时会对函数进行改名,而c编译器不会
extern "C" _declspec(
dll
export) int Mi
静态
加载
比较方便,
动态
加载
比较灵活一些,对于不常用的代码,可以在使用时LoadLibrary,在不用时FreeLibrary,不必长时间占用内存资源。有些情况(例如导出类)只能用
静态
加载
的
方式
。从代码维护角度来说,两者差别不大,用
静态
略微方便一些。
静态
加载
,简单方便,但是不够灵活
动态
加载
,复杂一些,需要显示地获取函数调用地址,但是很灵活,可以随时
加载
和卸载
------------...
在程序正在使用的过程中,常常需要升级
DLL
。这时,如果
dll
已经被主程序引用,则无法修改,这样的需求应该很常见。换个角度,可以理解成程序的升级或者修改Bug的功能。
以下通过
动态
的
加载
Dll
来解决这个问题。
整个思路的前提是,
动态
调用的东西和前台需要的功能通过代理IBaseInterface连接起来,也就是说
动态
dll
里面的类和Proxy都需要实现这个接口。
namespace Base...
1.
动态
加载
动态
库
LoadLibrary("xxxx.
dll
") // 宏函数 依据项目定义字符格式决定函数版本
LoadLibraryA("xxxx.
dll
")// 窄字符版本
LoadLibraryW("xxxx.
dll
")// 宽字.
如果你有a.
dll
和a.lib,两个文件都有的话可以用
静态
加载
的
方式
:
message函数的声明你应该知道吧,把它的声明和下面的语句写到一个头文件中
#pragma comment(lib, "a.lib")
然后你的对话框.cpp中包含这个头文件就可以使用message函数了。
动态
加载
:
如果
dll
没有对应的.lib文件,那么就只能使用
动态
加载
的
方式
了。
所谓"程序库",简单说,就是包含了数据和执行码的文件。其不能单独执行,可以作为其它执行程序的一部分,来完成执行功能。库的存在,可以使得程序模块化,可以加快程序的再编译,可以实现代码重用,可以使得程序便于升级。程序库可分三类:
静态
库,共享库和
动态
加载
库:
静态
库,是在执行程序运行前就已经加入到执行码中,在物理上成为执行程序的一部分;
共享库,是在执行程序启动时
加载
到执行程序中,可以被多个执行程...
在Windows中,
动态
链接库(Dynamic Link Library,
DLL
)是一种二进制文件格式,它们可以被
加载
到内存中作为一个可执行模块,用于提供特定的功能或服务。一般情况下,程序在运行时需要使用某些
DLL
文件来执行特定的任务,比如用户界面、网络连接、多媒体等等。
有时候,在程序运行过程中,可能需要
动态
加载
某些
DLL
文件来执行特定的功能。这时候就需要使用c语言中的
动态
库
加载
机制,通过编程来实现从硬盘上
加载
DLL
到内存中,然后在程序中调用其中的函数或操作。
在C语言中,可以通过使用Windows API函数LoadLibrary和GetProcAddress来实现
加载
DLL
文件的过程。首先,程序需要调用LoadLibrary函数来将
DLL
加载
到内存中,将其句柄(handle)保存在一个变量中。然后,程序可以使用GetProcAddress来获取
DLL
中特定函数的地址,进而调用这些函数。
需要注意的是,
加载
DLL
文件会增加程序的内存使用量,如果
加载
过多的
DLL
文件可能会使程序出现内存泄漏或者内存碎片等问题。因此,在编程中应该慎重考虑是否需要使用
动态
加载
DLL
文件的
方式
来实现特定功能。
lmw0320:
RTSP over UDP与RTSP over TCP取流对比
lmw0320:
欧拉回路判断
Zhaoge2334:
C++函数和变量的声明、定义的原因和作用
kekeke_k_e_: