美文网首页
动态链接库

动态链接库

作者: Asura_Luo | 来源:发表于2018-05-20 01:43 被阅读0次

    静态链接库的缺陷

    • 链接时将函数加入到exe导致exe变大
    • 在运行时对于不同进程他们所使用的同一个函数都会独占空间,造成资源浪费

    怎么解决

     利用之前学习过的内存知识,例如映射类型的内存块
     将这些公共代码放在文件中没在进程运行的时候在加载该文件
     并且在内存中只需要加载一边,不同进程使用同一份公共代码时,只需要将之前加载过的这个文件映射到自己内存中即可
    
    image.png

    什么是动态链接库

    动态链接库(dynamic link library 缩写位 dll),是微软公司在windows操作系统中
    实现共享函数库概念的一种方式

    这些库函数的扩展是 .dll .ocx(包含activeX控制的库)

    创建动态链接库

    1. extern "C" _declspec(dllexport) 返回类型 调用约定 函数名 (参数列表)
    2. 使用.def文件
      制定导出函数,并告知编译器不要以修饰后的函数名作为导出函数名,而以指定的函数名导出函数
    EXPORTS
    函数名   @编号
    函数名   @编号    NONAME
    

    使用序号导出的好处:

    名字是一段程序最精华的注释,通过名字可以直接猜到函数的功能
    通过使用序号,可以达到隐藏的目的

    如何调用动态链接库(显式调用)

    1. 定义函数指针
    2. 声明函数变量
    3. 通过LoadLibrary() 动态加载DLL到内存中
    4. 通过GetProcAddress()获取函数地址
    5. 调用函数
    6. FreeLibrary()释放动态链接库

    exp:

    // 定义
    // MyFunction.h
    //根据名字查找进程id
    //extern "C" _declspec(dllexport) 返回类型 调用约定 函数名 (参数列表)
    extern "C" _declspec(dllexport) DWORD _stdcall find_processid_by_name(PWCHAR process_name);
    
    // MyFunction.cpp
    #include "stdafx.h"
    #include <Windows.h>
    #include <TlHelp32.h>
    
    DWORD find_processid_by_name(PWCHAR process_name)
    {
    
        HANDLE hand = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
        if ((int)hand == -1)
        {
            return GetLastError();
        }
        PROCESSENTRY32 process_info = { 0 };
        process_info.dwSize = sizeof PROCESSENTRY32;
    
        if (!Process32First(hand, &process_info))
        {
            return GetLastError();
        }
    
        do
        {
            if (!wcscmp(process_info.szExeFile, process_name))
            {
                return process_info.th32ProcessID;
            }
    
        } while (Process32Next(hand,&process_info));
        return 0;
    }
    
    
    //调用
    //Main.cpp
    #include "stdafx.h"
    #include "windows.h"
    
    //显示的导入
    
    //1 定义函数指针
    typedef DWORD(_cdecl * PFindProcessW)(PWCHAR);
    //2 定义变量
    PFindProcessW pMyFindProcessW = NULL;
    
    
    int main()
    {
        //3 装载DLL
        HMODULE hModule = LoadLibrary(L"动态链接库.dll");
    
        //4 获得函数
    
        pMyFindProcessW = (PFindProcessW)GetProcAddress(hModule, "find_processid_by_name");
        DWORD err = GetLastError();
    
        WCHAR name[] = L"notepad.exe";
        printf_s("PID=%d \r\n", pMyFindProcessW(name));
        getchar();
        return 0;
    }
    
    

    DLL和EXE的区别

    • 动态链接库DLL与可执行文件exe本质上没有区别,我们统称为模块
    • 他们内部的数据组织结构都遵循一个叫做PE文件格式的格式
    • 两者都可以对外提供函数,只不过DLL提供的更多

    相关文章

      网友评论

          本文标题:动态链接库

          本文链接:https://www.haomeiwen.com/subject/ykkzdftx.html