zoukankan      html  css  js  c++  java
  • 动态链接库DLL

    1、动态库简介:
    动态链接库可以看成是一种仓库,一种资源的集合:函数,变量,类,资源……都可以由动态链接库来导出。

    2、动态库与静态库的区别:
    a、静态库中的代码会直接塞到EXE中,而动态库则可以被EXE动态的加载或卸载;
    b、静态库中不能再包含其他的动态或静态库,而动态库则可以。

    3、实现方式:
    动态库可以被多种语言来实现,只要遵循动态库的接口规范和调用方式即可,用各种语言编写的动态库也都可以互相调用。比如Windows系统提供的动态库,在任何开发语言的编译器上都可以调用,VB,VC,Delphi,C# 等等。

    4、Vc++编译器中动态库的分类:
    ① 非MFC的DLL -- 即使用 SDK API 进行编程,能被其他所有语言调用;
    ② MFC规则DLL --- 可以使用 MFC 进行编程,能被其他所有语言调用;

    ③ MFC扩展DLL --- 可以使用 MFC进行编程,但只能被用MFC编写的程序调用。

    5、DLL程序入口点函数:
    CUI控制台程序(不是DOS):main
    GUI用户界面程序:WinMain
    DLL程序入口点函数:DllMain,注意:大小写是区别的(仅导出资源的DLL可以没有DllMain函数)。为大家讲解下具体的参数的应用。
    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
                         )
    {
        return TRUE;
    }

    ①hModule参数:指向DLL本身的实例句柄;

    ②ul_reason_for_call参数:指明了DLL被调用的原因,可以有以下4个取值:
    ■DLL_PROCESS_ATTACH:
    当DLL被进程 <<第一次>> 调用时,导致DllMain函数被调用,同时ul_reason_for_call的值为DLL_PROCESS_ATTACH,如果同一个进程后来再次调用此DLL时,操作系统只会增加DLL的使用次数,不会再用DLL_PROCESS_ATTACH调用DLL的DllMain函数。
    ■DLL_PROCESS_DETACH:
    当DLL被从进程的地址空间解除映射时,系统调用了它的DllMain,传递的ul_reason_for_call值是DLL_PROCESS_DETACH。
    ★如果进程的终结是因为调用了TerminateProcess,系统就不会用DLL_PROCESS_DETACH来调用DLL的DllMain函数。这就意味着DLL在进程结束前没有机会执行任何清理工作。
    ■DLL_THREAD_ATTACH:
    当进程创建一线程时,系统查看当前映射到进程地址空间中的所有DLL文件映像,并用值DLL_THREAD_ATTACH调用DLL的DllMain函数。 新创建的线程负责执行这次的DLL的DllMain函数,只有当所有的DLL都处理完这一通知后,系统才允许线程开始执行它的线程函数。
    ■DLL_THREAD_DETACH:
    如果线程调用了ExitThread来结束线程(线程函数返回时,系统也会自动调用ExitThread),系统查看当前映射到进程空间中的所有DLL文件映像,并用DLL_THREAD_DETACH来调用DllMain函数,通知所有的DLL去执行线程级的清理工作。
    ★注意:如果线程的结束是因为系统中的一个线程调用了TerminateThread,系统就不会用值DLL_THREAD_DETACH来调用所有DLL的DllMain函数。

    /*********************************************************************/
    还是请大家多多注意我★号的2个地方,此外ul_reason_for_call参数多采用 switch-case 结构类型。
    /*********************************************************************/

    ③lpReserved参数:保留,目前没什么意义。

    6、DLL导出函数:DLL只有将函数进行导出,这样其他的程序才可以进行调用。

    DLL里面可以有2种函数:一种是导出函数,供被DLL调用的程序使用,比如说是EXE等;另外一种是供DLL内部调用使用,不提供导出。

    7、DLL导出函数的方式:*.def 文件或 __declspec(dllexport) 关键字:

    ①*.def 文件必须至少包含下列模块定义语句:

    ■文件中的第一个语句必须是 LIBRARY 语句。此语句将 .def 文件标识为属于 DLL。LIBRARY 语句的后面是 DLL 的名称。链接器将此名称放到 DLL 的导入库中。

    ■EXPORTS 语句列出名称,可能的话还会列出 DLL 导出函数的序号值。通过在函数名的后面加上 @ 符和一个数字,给函数分配序号值。当指定序号值时,序号值的范围必须是从 1 到 N,其中 N 是 DLL 导出函数的个数。

    ■注释语句,在语句前面加分号 “;” 。

    例如:
    ;DLLTest.def : Declares the module parameters for the DLL.
    LIBRARY   "DLLTest"
    EXPORTS    add   @1

     

     

     使用Vc++自带的Depends工具进行查看,但是只能看到函数的名字,具体的函数参数及返回值看不到,所以要把动态库导出函数声明的头文件(.h文件)打包给<<开发者>> 。

     

     ②_declspec(dllexport) 导出方式:
    为了防止名字改编,将 extern "C" _declspec(dllexport) 语句放在想要导出函数的声明前面;
    例如:
    extern "C" _declspec(dllexport) int add(int a, int b);

    注:如果要进行函数的导入则把dllexport换成dllimport即可,如:extern "C" _declspec(dllimport) 。

     

  • 相关阅读:
    svn使用教程各种杂七杂八!
    Python+Django+Eclipse 在Windows下快速网站
    Python Django 框架开发
    【多肉】播种育苗 友情推荐:教你如何买到真种子
    (十一)Json文件配置
    (十)命令行配置
    (九)配置介绍
    visual studio 注释模板
    使用批处理自动发布IIS站点,基于IIS7及以上
    Win10系统无法安装可选功能提示错误代码0x800F081F的解决方法
  • 原文地址:https://www.cnblogs.com/tt_mc/p/1652607.html
Copyright © 2011-2022 走看看