欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

动态链接库DLL的加载

程序员文章站 2022-06-25 18:46:06
...

《程序员的自我修养--链接、装载与库》学习笔记

动态链接(DLL)

DLL,即动态链接库(Dynamic Link Library),在实际应用开发过程中,为了以后对已经开发好的软件程序进行更好的维护和管理,程序的模块化是一个很好的管理方法,程序员大都喜欢把某一模块的功能做成dll文件,然后导入到工程目录中,再进行加载即可调用dll里面的函数,大大的减少了代码的阅读量,节省大量的宝贵时间,如果需要对dll里面的具体方法进行修改,直接打开生成dll文件即可,不需要在整个工程项目中查找,如果工程量较大,那查找其中某一个模块必定是一件费时的事情。那也说明了dll/模块化细想的重要性。

DLL加载方式

静态加载:

  • lib中的函数不仅被连接,而且全部实现都被直接包含在最终生成的EXE文件中,但是其具体实现是不可见的。
  • 静态调用中,由编译系统完成对DLL的加载和应用程序结束时DLL的卸载:释放已经加载的DLL模块: FreeLibrary(hDll);
  • 静态调用:.cpp文件中包含对应的.h文件,并写上如下语句:
#pragma comment(lib,"xxx.lib") //告诉编译器DLL相对应的lib文件所在路径和文件名
extern "C" _declspec(dllimport) int _stdcall Camera();//声明导入函数

动态加载:

  • dll不必被包含在最终的EXE中,动态调用时仅把函数名或者变量名或者类名链接到.EXE文件中,而这些东西的实体都只有在运行时才从动态库中导入到可执行。文件中,动态调用中.EXE文件执行时可以直接动态地引用和卸载DLL文件。
  •  动态调用中,由程序员用API函数加载和卸载DLL。 方式:(DLL加载—DLL函数地址获取—DLL释放)

DLL导入导出

  • _declspec:在函数声明类型和函数名之间加上
__declspec(dllexport) double  Add(double a, double b);
__declspec(dllexport) double  Sub(double a, double b);
__declspec(dllexport) double  Mul(double a, double b);

extern “C” __declspec(dllexport) double  Cal(double a, double b);
  • .def:采用模块定义(.def)文件声明,需要在库工程中添加模块文件
LIBRARY Math
EXPORTS 
Add
Sub
Mul
Cal

DLL动态加载demo

#include <windows.h>
#include <stdio.h>

typedef double (*Func)(double, double);

int main(int argc, char** argv)
{
    // load dll
    HINSTANCE hinstLib = LoadLibrary("Mathh.dll");
    if (!hinstLib)
    {
        printf("ERROR: unable to load DLL\n");
        return 1;
    }

    // get function
    Func function = (Func)GetProcAddress(hinstLib, "Add");
    if (!function)
    {
        printf("ERROR: unable to find DLL function\n");
        FreeLibrary(hinstLib);
        return 1;
    }

    // call function
    double result = function(1.0, 2.0);

    // unload DLL file
    FreeLibrary(hinstLib);

    return 0;
}