zoukankan      html  css  js  c++  java
  • 【笔记】刚到公司,初识dll

        刚到公司,发了一个本子一支笔一个文件夹(VC++深入详解、C++ Primer、Effective C++、Effective STL)。

        废话不多说,第一项任务:熟悉VS,联系创建dll文件,并从中导出函数供应用程序使用。

    一、简介一下dll

        DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数、变量或类。通常不能直接运行,也不能接收消息。它们是一些独立的文件,只有当其他模块调用dll中的函数时,才发挥作用。

        Windows API 中所有的函数都包含在dll中,有三个最重要的:

        1、Kernel32.dll:包含用于管理内存、进程和线程的函数。

        2、User32.dll:包含用于执行用户界面任务的函数。

        3、GDI32.dll:包含哪些用于画图和显示文本的函数。

        【静态库】

        函数和数据被编译进一个二进制文件(.lib)。编译连接时,复制这些函数和数据,把它们和应用程序的其它模块组合起来,创建最终的可执行文件(.exe)。发布产品时只需发布可执行文件,不需要发布静态库。

       【动态库】

        动态库往往提供两个文件:

        引入库文件(.lib)——包含导出的函数和变量的符号名。

        DLL文件(.dll)——包含该DLL实际的函数和数据。

        编译链接时不复制,运行时才加载(将DLL映射到进程的地址空间中),然后访问导出函数。发布产品时除了可执行文件,还要有动态链接库。

    二、从dll中导出函数(采用隐式加载dll)

    1、新建一个dll,在dll.cpp中写两个简单的函数:

       int add(int a, int b)

       {  return a + b;

       }

       int subtract(int a,int b)

       {  return a = b;

       }

       点击生成dll,则会在debug目录下产生11个文件,其中包含.lib和.dll文件。

    2、在想要导出的函数前,加上导出标志符:_declspec(dllexport)。如下:

       _declspec(dllexport) int add(int a,int b)    {  return a+b;    }    _declspec(dllexport)int subtract(int a,int b)    {  return a-b;    }

    3、创建一个基于对话框的应用程序test.exe。

       //在testDlg.cpp中声明函数    extern int add(int a,int b);    extern int subtract(int a,int b);

      //接着实现两个按钮的消息映射函数

       void CtestDlg::OnBnClickedBtnAdd()   {     OnBtnAdd();//手动添加   }

       void CtestDlg::OnBnClickedBtnSubtract()   {      OnBtnSubtract();//手动添加   }

       void CtestDlg::OnBtnAdd(void)   {      CString str;      str.Format("5 + 3 = %d",add(5,3));      MessageBox(str);

      }

       void CtestDlg::OnBtnSubtract(void) {      CString str;      str.Format("5 - 3 = %d",subtract(5,3));      MessageBox(str);

      } 4、编译一下,出现三个错!没有载入dll......

       将刚才生成的.lib和.dll两个文件复制到test所在目录下。

       编译还是错!没有设置库......

       在项目--属性--链接器--输入--附加依赖项--填写“dll.lib”

       再次生成exe就好啦!

    三、从dll中到处类(采用隐式加载dll)

    先注明一点:不是导出就一定能够使用该类,仍旧受限于类本身的访问权限!

    1、在dll.h中写一个类,并添加导出标志符:    class  _declspec(dllexport) Point   {     public:        void output(int x,int y);   };   在dll.cpp中实现:

      void Point::output(int x,int y)   {     //返回调用者进程当前正在使用的那个窗口的句柄       HWND hwnd = ::GetForegroundWindow();    //获取DC       HDC hdc = ::GetDC(hwnd);       char buf[20];       memset(buf,0,20);       sprintf(buf,"x = %d,y = %d",x,y);    //输出坐标       ::TextOut(hdc,0,0,buf,strlen(buf));    //释放DC      ::ReleaseDC(hwnd,hdc);

      }    因为用到库函数,所以在dll.cpp中包含头文件:

       #include "Windows.h"    #include "stdio.h" 2、在test.cpp中使用这个类:

       void CtestDlg::OnBtnOutput(void)   {      Point pt;      pt.output(5,3);

       }

      当然,也要包含定义类的头文件:

       #include "dll.h" 3、将.lib和.h文件放在test目录下,将.dll文件放在test\debug目录下。

    4、编译生成exe,完成。

    【使用宏定义】

    1、在dll.h文件中添加一个宏:

       #ifdef AAAA

       #define DLL_API _declspec(dllexport)

       #else

       #define DLL_API _declspec(dllimport)

       #endif

       则定义类如下:

       class  DLL_API Point    {      public:        void output(int x,int y);    };

    2、在stdafx.h中:#define AAAA

    (dll.cpp包含了stdafx.h所以就是export啦!testDlg.cpp中没有定义,所以就是impoort!)

     参考资料:VC++深入详解——孙鑫

  • 相关阅读:
    JavaBean 之Hello World(入门实例)
    Velocity之Hello World(入门实例)
    URL, URI 和 URN 之间的区别
    Windows平台的Windbg/x64dbg/OllyDbg调试器简介以及符号文件*.pdb总结(★firecat推荐★)
    VC++内存泄漏检测方法(5):使用强大的Windbg工具,重点是Symbols Path设置
    安装与配置windbg 的符号文件(转自一片文章的回复,回复者RegKiller)
    WinDbg下载符号文件(内核层、用户层)
    Windbg下载微软符号表
    windbg符号表问题
    WinDBG加载符号表的一点心得体会
  • 原文地址:https://www.cnblogs.com/xxt1991/p/dll_first.html
Copyright © 2011-2022 走看看