在某项目中,需要使用两个不同版本的HCNetSDK库,我们通常使用的静态加载DLL的方式不能满足该需求,故用到动态加载DLL的方式。

  • 背景技术及术语解释

静态加载:也称隐式调用,指在运行程序之前由操作系统的加载器将DLL和EXE一起加载到内存里。注意这里与程序的静态链接区别开来,静态链接发生在编译过程之中,而DLL的静态加载是发生在程序运行之前。

动态加载:也称显示调用,指应用程序运行过程中程序自己完成对DLL的加载和卸载(DLL加载—DLL函数地址获取—DLL释放),应用程序在执行过程中随时可以加载DLL文件,也可以随时卸载DLL文件。

  1. 静态加载 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中的接口。

  1. 动态加载 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. 静态加载与动态加载区别

(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: gstreamer的命令是:appsrc ! video/x-raw, format=BGR ! queue ! videoconvert ! video/x-raw,width=1920,height=1080 ! queue ! x264enc ! queue ! video/x-h264, stream-format=byte-stream ! h264parse ! rtph264pay pt=96 config-interval=1 ! udpsink host=127.0.0.1 port=5400 我不是很明白几点: 1. 对于不同视频流的输入,我推送到udp上,是否也要推送到不同的udp端口去? 这样rtsp获取的时候,也根据不同的端口来获取不同的流?只要设置factory的不同名称(对rtsp的端口只要一个就可以, 而通过不同的factory名称来区别不同的流??) 2. 这么一长串的命令,实在看得云里雾里的,完全不知道具体的流是如何转换的,是否有必要用这么长的命令来实现? RTSP over UDP与RTSP over TCP取流对比 lmw0320: 请教下,我目前的需求是想将边缘设备上的获取到多个摄像头的帧数据,进行处理后,转成RTSP流的方式推送出去,要怎么做才是合适的呢? 之前的方案是将图片数据推送到udp服务中,然后起个rtsp的服务,从udp中取流,再推送。 看博文的意思,其实用tcp可能更好? 对这块完全不了解,求指点。。 欧拉回路判断 Zhaoge2334: 判断节点度真的是一点技术都。。。。 C++函数和变量的声明、定义的原因和作用 kekeke_k_e_: