美文网首页
编程技巧分享之so的初始化

编程技巧分享之so的初始化

作者: 潜水企鹅 | 来源:发表于2020-06-07 17:00 被阅读0次

    假设我们需要提供一个 so 给其他人用,并这个 so 需要执行初始化动作,你会怎么来设计?

    方法1:简单粗暴

    这种方法应该是最容易想到到的,直接简单粗暴,提供接口,让调用者来处理,示例如下:

    /****** method1.c ******/   
    void method1_init(void)
    {
        printf("calling method1_init...\r\n");
    }
    
    void method1_dosomething(void)
    {
        printf("calling method1_dosomething...\r\n");
    }
    
    
    /****** main.c ******/
    extern void method1_init(void);
    extern void method1_dosomething(void);
    
    int main(int argc, char *argv[])
    {
        printf("test main run...\r\n");
    
        method1_init();
        method1_dosomething();
    
        return 0x00;
    }
    

    方法2:安能辨我是雌雄

    直接上码再说吧。

    /***** method2.c *****/
    void __method2_init(void);
    void __method2_dosomething(void);
    
    static void (*fun)(void) = __method2_init;
    
    void __method2_init(void)
    {
        printf("calling method2_init...\r\n");
    
        fun = __method2_dosomething;
    
        fun();
    }
    
    void __method2_dosomething(void)
    {
        printf("calling method2_dosomething...\r\n");
    }
    
    void method2_dosomething(void)
    {
        fun();
    }
    
    /****** main.c ******/
    extern void method2_dosomething(void);
    
    int main(int argc, char *argv[])
    {
        printf("test main run...\r\n");
    
        method2_dosomething();
    
        return 0x00;
    }
    

    这里的 method2_dosomething 接口既是提供服务的接口也是初始化的接口。

    只会在第一次调用它的时候执行 init 动作,这里利用了函数指针,对调用者来说非常的友好。

    严格来做这里的静态函数指针变量相当于引入了状态,在多线程调用过程中需要加锁。

    方法3:GCC 的黑魔法

    这里用到了 gcc 的一个设置函数属性的功能,让其在加载过程自动的被调用,如下:

    /***** method3.c *****/
    __attribute__((constructor)) void __method3_init(void)
    {
        printf("calling method3_init...\r\n");
    }
    
    void method3_dosomething(void)
    {
        printf("calling method3_dosomething...\r\n");
    }
    
    /****** main.c ******/
    extern void method3_dosomething(void);
    
    int main(int argc, char *argv[])
    {
        printf("test main run...\r\n");
    
        method3_dosomething();
    
        return 0x00;
    }
    

    被 <code>__attribute__((constructor))</code> 修饰的函数会先于 main 函数执行,同时会自动的被调用。

    这种方法得益于编译器的支持,对于调用者来说也是非常友好,同时不需要像方法2一样在多线程使用中需要用到锁的机制,此种方法实现更简单。

    好了,这里主要介绍三种怎么处理一个模块初始化的方法,三种各有优缺点吧,适合才是最好的,项目中选择最适合自己实际情况的方法就好。

    如果你有更好的方法或想法,欢迎评论留言,谢谢!

    扫码关注我了解更多

    相关文章

      网友评论

          本文标题:编程技巧分享之so的初始化

          本文链接:https://www.haomeiwen.com/subject/goictktx.html