在静态库中,实现自动的初始化与卸载接口

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

其实就是类似于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被卸载时,自动执行了析构函数,这不正是自动初始化与卸载的接口吗?

 

你可能感兴趣的:(初始化)