zoukankan      html  css  js  c++  java
  • 在静态库中,实现自动的初始化与卸载接口

    所谓自动的自动初始化与自动卸载

    其实就是类似于dll中的DllMain函数,或者MFC DLL中的InitInstance与ExitInstance更为贴切(其实这两个也是从DllMain调用过来的)。

    也就是当调用静态库的PE文件加载时,自动初始化,PE文件释放时,自动执行卸载

    这个作用,看似不怎么样,实际运用中,处理好之后则可能省去很多麻烦的代码。


    你封装在静态库中的代码,通常应该是较为通用的代码,我个人写程序,是把一个静态库当作自己的核心开发库来使用,静态库中包含的接口,通常是一些便捷功能的API封装,或者一些通用的算法,在开发过程中,又慢慢的把常用、通用的代码封装到静态库中,时间长了,累积的东西多了,以后的项目开发起来效率会非常的高。


    当你的静态库累积得很大的时候,某些接口需要初始化某个全局变量时,某些接口需要动态的分配内存,或者某些接口会创建资源,比如在静态库中实现文件访问的互斥机制时,在静态库中动态创建窗口时,或者Inline Hook接口中自动分配的内存来实现shell code时,反正需要分配资源,又通用,常用的代码,有很多种,说是说不完的。


    在这些情况下,如果没有初始化与卸载接口,这些功能会变得很麻烦,所以大多数人是实现了初始化与卸载接口来显式调用。


    看到这里,其实你应该会想,这就是个无聊的文章,也就是为了省两行代码而已,有必要吗?事实上确实如此,本人就是那么无聊,就为了省两行代码浪费这么多表情和时间。至于你是否需要浪费这个时间看下去,那就不关我的事了。


    那么,从根本问题来考虑,我们需要在静态库中实现一个跟随程序加载的Main函数,当然要类似DllMain是不可能的,因为这个接口并不是由我们自己调用的。我们要选择更合理的方式,也就是之前提到的类似MFC DLL的方式。


    面向对象编程最基础的特性,构造函数与析构函数,是这个功能的核心,看到这句话可能大多数人知道该怎么做了。


    在静态库的某个CPP中:

    class CStaticLibraryMain

    {

    public:

        CStaticLibraryMain()

        {

            //初始化....

        }


        ~CStaticLibraryMain()

        {

            //卸载...

        }


        bool LinkProc()

        {

            return true;

        }

    };


    CStaticLibraryMain m_LibMain;

    bool m_bLinkVal = m_LibMain.LinkProc();


    在你静态库的头文件中

    extern bool m_bLinkVal;

    static bool m_bLinkVal2 = m_bLinkVal;


    就是这么简单,LinkProc, m_bLinkVal, m_bLinkVal2这些个玩意,都是为了实现自动链接而存在的,因为静态库中的全局变量,只有在你代码中确实访问到这个变量,才会在链接器在编译代码时,才会选择分配它的内存,一层层的链接过去,最终访问到m_LibMain时,自动执行了构造函数,而在你的程序停止时,或者DLL被卸载时,自动执行了析构函数,这不正是自动初始化与卸载的接口吗?

  • 相关阅读:
    Git -- 撤销修改
    Git -- 管理修改
    Git -- 相关命令
    Git -- 工作区 和 暂存区
    Git -- 基本操作 之 版本回退
    Git -- 创建版本库
    Git -- 安装
    Git -- 简介
    word文档下划线无法显示的解决方法
    The data protection operation was unsuccessful. This may have been caused by not having the user profile loaded for the current thread's user context,
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3144764.html
Copyright © 2011-2022 走看看