zoukankan      html  css  js  c++  java
  • DLL学习

    创建工程:win32->dll

    静态库:lib在编译连接时copy进去后生成exe文件

    动态库使用:

    1. 引入库(dll文件导出函数和变量符号名)(编译连接时使用,不复制dll文件里的函数和变量)
    2. dll文件(实际函数和数据)(程序运行时加载相应的函数)

    隐式链接:

    查看动态链接库中的导出函数

    dumpbin工具

    dumpbin  –exports  *.dll(大小写无关)

    __declspec(dllexport)   int fun(){   

    }

    42_thumb4

    为了支持C++重载(同名)       名字粉碎所以名字乱

    1. extern int myadd(int a,int b);
    2. __declspec(dllimport)   int myadd(int a,int b);

    dll工程会同时产生dll文件和lib引入库

    link->lib引入库

    43_thumb

    44_thumb2

    查看可执行文件的输入信息

    dumpbin  –imports  *.exe(大小写无关)

    45_thumb

    46_thumb

    testdll.exe 与dll1.dll同一个目录下,上面是exe文件的依赖库,下面是依赖库的导出函数

    提供头文件给用户使用。

    .h

    __declspec(dllimport)   int fun1(int a,int b);
    __declspec(dllimport)   int fun2(int a,int b);
    __declspec(dllimport)   int fun3(int a,int b);
    ......
    ......

    包含以上头文件使用即可

    //导出类
    class DLL1_API Cdll1 {
    public:
        Cdll1(void);
        // TODO: 在此添加您的方法。
    };
    //仅仅导出类中的某些函数
    class  Cdll1 {
    public:
        Cdll1(void);
        // TODO: 在此添加您的方法。
        DLL1_API  void fun();//导出该方法
    };

    虽然类没有导出,但仍然可以构造对象

    注意:定义类的方法全部要在cpp文件里实现,否则会出错!包括构造函数!

    class   Cdll2 {   //虽然整个类不是导出的但是,构造函数一定要导出,否则生成对象会链接出错
    public:
        DLL1_API Cdll2(void);
        // TODO: 在此添加您的方法。
         DLL1_API void fun2();
        void fun3();
    
    };
    #define DLL1_API   extern "C" __declspec(dllexport)//导出名字与函数名字一样
    DLL1_API int _stdcall fun();//win_api调用约定
    DLL1_API int fun();//c++调用约定
    //粉碎命名规则不一样!


    模块定义文件:

    *.def   调用约定不会改变粉碎命名规则!

    LIBRARY dll1
    EXPORTS
    //导出函数名字,与cpp文件定义的要导出的同名

    cpp中就不需要

    DLL1_API int fun();//


    动态加载     启动快速,节约内存资源

    映射可执行模块到调用进程的地址空间

    HMODULE LoadLibrary(
      LPCTSTR lpFileName   // file name of module
    );

    加载dll和exe

    LPCTSTR lpFileName 指向dll和exe地址的字符串指针

    得到导出函数地址:

    FARPROC GetProcAddress(
      HMODULE hModule,    // handle to DLL module
      LPCSTR lpProcName   // function name
    );

    动态加载 一般要有extern "C"

    extern "C" DLL1_API int myadd(int a,int b)
    {
        return a+b;
    }

    47_thumb

        HINSTANCE hinst;
        hinst=LoadLibrary("dll1.dll");
        typedef int (*ADDPROC)(int a,int b);
        ADDPROC ad=(ADDPROC)GetProcAddress(hinst,"myadd");
        // typedef int (_stdcall *ADDPROC)(int a,int b); 调用约定改变时
        if (!ad)
        {
            printf("没有得到函数地址失败!");
            return 0;
        }
        int i=ad(4,7);
        printf("%d
    ",i);

    否则会报“没有得到函数地址”的错误

    48_thumb

    此时

    dumpbin  –imports  *.exe

    没有dll1.dll的信息

    命令行下的复制 ,选择->右键->已经复制成功!

    ADDPROC ad=(ADDPROC)GetProcAddress(hinst,MAKEINTRESOURCE(dumpbin ordinal));
     

    DLLMain()函数

    BOOL WINAPI DllMain(
      HINSTANCE hinstDLL,  // handle to the DLL module
      DWORD fdwReason,     // reason for calling function
      LPVOID lpvReserved   // reserved
    );

    dll加载时,句柄传递进来可以给其他程序(通过进程间的通信:管道等)使用

    _thumb

    主要dll.cpp文件里有DllMain()则,dll被加载时,自动调用DllMain()函数


    新建mfc支持的dll

    regular dll   using shared mfc dll 用户机器上得有mfc dll 才可以运行你的MFC dll(自己的c++类可以导出)

    mfc extension dll 导出mfc类


    BOOL FreeLibrary(
      HMODULE hModule   // handle to DLL module
    );
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    ASP.NET MVC分部类的使用
    窗体初始化完毕后隐藏窗体
    让每个用户都有同样的输入法配置
    昨夜的失眠--从数据备份所想到的.
    电子书下载
    Microsoft .Net 框架 SDK 快速入门教程
    .net书籍代码下载 [雪冬寒'Blog]
    VISUAL C#.NET中文版WEB服务开发基础
    Citrix相关技术
    OA在线试用
  • 原文地址:https://www.cnblogs.com/yuliyang/p/3392915.html
Copyright © 2011-2022 走看看