boringssl DEFINE_LOCAL_DATA

这篇具有很好参考价值的文章主要介绍了boringssl DEFINE_LOCAL_DATA。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ecb_generic) 
{
  memset(out, 0, sizeof(EVP_CIPHER));

  out->nid = NID_aes_192_ecb;
  out->block_size = 16;
  out->key_len = 24;
  out->ctx_size = sizeof(EVP_AES_KEY);
  out->flags = EVP_CIPH_ECB_MODE;
  out->init = aes_init_key;
  out->cipher = aes_ecb_cipher;
}

代码看着有点别扭,就是怕别人看懂了,写出这么个玩意。

看DEFINE_LOCAL_DATA 定义 !

#define DEFINE_LOCAL_DATA(type, name) DEFINE_DATA(type, name, static const)

------------------------------------------------------------------------------、

所以DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ecb_generic) = 

DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ecb_generic) = 

DEFINE_DATA(EVP_CIPHER, aes_192_ecb_generic, static const)

继续看DEFINE_DATA(EVP_CIPHER, aes_192_ecb_generic, static const)

#define DEFINE_DATA(type, name, accessor_decorations)                         \
  DEFINE_BSS_GET(type, name##_storage)                                        \
  DEFINE_STATIC_ONCE(name##_once)                                             \
  static void name##_do_init(type *out);                                      \
  static void name##_init(void) { name##_do_init(name##_storage_bss_get()); } \
  accessor_decorations type *name(void) {                                     \
    CRYPTO_once(name##_once_bss_get(), name##_init);                          \
    /* See http://c-faq.com/ansi/constmismatch.html for why the following     \
     * cast is needed. */                                                     \
    return (const type *)name##_storage_bss_get();                            \
  }                                                                           \
  static void name##_do_init(type *out)

DEFINE_DATA定义见上面的代码,继续拆~

#define DEFINE_BSS_GET(type, name) \
  static type name;                \
  static type *name##_bss_get(void) { return &name; }

#define DEFINE_STATIC_ONCE(name)                \
  static CRYPTO_once_t name = CRYPTO_ONCE_INIT; \
  static CRYPTO_once_t *name##_bss_get(void) { return &name; }

void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) {
  if (*once) {
    return;
  }
  *once = 1;
  init();
}

#define DEFINE_DATA(EVP_CIPHER, aes_192_ecb_generic, accessor_decorations)    
// 以下当做一个代码块 { }括起来
{
    //1. DEFINE_BSS_GET(type, name##_storage)  
    {
        //1.1 定义变量aes_192_ecb_generic##_storage;
        static EVP_CIPHER aes_192_ecb_generic##_storage;    
        //1.2 定义函数aes_192_ecb_generic##_storage##_bss_get
        static EVP_CIPHER *aes_192_ecb_generic##_storage##_bss_get(void) 
        { 
            return &aes_192_ecb_generic##_storage; 
        }
    }
                                     
    //2. DEFINE_STATIC_ONCE(name##_once) 
    {
        //2.1 定义变量aes_192_ecb_generic##_once
        static CRYPTO_once_t aes_192_ecb_generic##_once = CRYPTO_ONCE_INIT;
        //2.2 定义函数aes_192_ecb_generic##_once##_bss_get
        static CRYPTO_once_t *aes_192_ecb_generic##_once##_bss_get(void) 
        { 
            return &aes_192_ecb_generic##_once; 
        }
    }

                                       
    //3. static void name##_do_init(type *out); 
    //3.1 声明函数 aes_192_ecb_generic##_do_init(type *out)
    static void aes_192_ecb_generic##_do_init(type *out); 
                                     
    //4. static void name##_init(void) { name##_do_init(name##_storage_bss_get()); } 
    //4.1 定义函数aes_192_ecb_generic##_init
    static void aes_192_ecb_generic##_init(void)
    {
        aes_192_ecb_generic##_do_init(aes_192_ecb_generic##_storage_bss_get()); 
    }

    //5. accessor_decorations type *name(void) 
    {                                     
        CRYPTO_once(name##_once_bss_get(), name##_init);                                                                              
        return (const type *)name##_storage_bss_get();                            
    }
    //5.1 定义函数aes_192_ecb_generic
    static const EVP_CIPHER *aes_192_ecb_generic(void) 
    {
        CRYPTO_once(aes_192_ecb_generic##_once_bss_get(), aes_192_ecb_generic##_init);
        return (const type *)aes_192_ecb_generic##_storage_bss_get(); 
    }
                                                                              
    //6. static void name##_do_init(type *out)
    //6.1 static void   aes_192_ecb_generic##_do_init(EVP_CIPHER *out)                

DEFINE_DATA(EVP_CIPHER, aes_192_ecb_generic, static const)展开内容如上所示

  • ## 运算符用于在预处理期粘连两个标识符
  • ## 的连接作用是在预处理期完成的,因此只在宏定义中有效
  • 编译器不知道 ## 运算符的存在

汇总下

DEFINE_DATA(EVP_CIPHER, aes_192_ecb_generic, static const)

{
  memset(out, 0, sizeof(EVP_CIPHER));

  out->nid = NID_aes_192_ecb;
  out->block_size = 16;
  out->key_len = 24;
  out->ctx_size = sizeof(EVP_AES_KEY);
  out->flags = EVP_CIPH_ECB_MODE;
  out->init = aes_init_key;
  out->cipher = aes_ecb_cipher;
}

做了以下事情

static EVP_CIPHER aes_192_ecb_generic_storage; 

       

static EVP_CIPHER *aes_192_ecb_generic_storage_bss_get(void) 

        return &aes_192_ecb_generic_storage; 
}

static CRYPTO_once_t aes_192_ecb_generic_once = CRYPTO_ONCE_INIT;

static CRYPTO_once_t *aes_192_ecb_generic_once_bss_get(void) 

        return &aes_192_ecb_generic_once; 
}

static void aes_192_ecb_generic_do_init(type *out);

static void aes_192_ecb_generic_init(void)
{
        aes_192_ecb_generic_do_init(aes_192_ecb_generic_storage_bss_get()); 
}

static const EVP_CIPHER *aes_192_ecb_generic(void) 
{
        CRYPTO_once(aes_192_ecb_generic_once_bss_get(), aes_192_ecb_generic_init);
         return (const type *)aes_192_ecb_generic_storage_bss_get(); 
}

static void aes_192_ecb_generic_do_init(EVP_CIPHER *out)   
{
         memset(out, 0, sizeof(EVP_CIPHER));

        out->nid = NID_aes_192_ecb;
        out->block_size = 16;
        out->key_len = 24;
        out->ctx_size = sizeof(EVP_AES_KEY);
        out->flags = EVP_CIPH_ECB_MODE;
        out->init = aes_init_key;
        out->cipher = aes_ecb_cipher;
}

aes_192_ecb_generic -》 

aes_192_ecb_generic_init -》

aes_192_ecb_generic_do_init 初始化EVP_CIPHER 结构体文章来源地址https://www.toymoban.com/news/detail-674490.html

到了这里,关于boringssl DEFINE_LOCAL_DATA的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • typedef 和 # define 用法区别

    博主在牛客网上看到了一道有关typedef和# define题目。发现有很多初学的小伙伴对两者的用法不是特别清楚,所以博主在这总结以下相关用法和区别。 话不多说,先来看看原题吧!(答案c) #define是C语言中定义的语法,是预处理指令,在预处理时进行简单而机械的替换,不作

    2024年02月08日
    浏览(43)
  • c++中的宏#define用途

    宏的一些作用,包括但不限于这些 定义一个变量、字符串、类型 定义一个函数、条件表达式 条件编译、调试信息,异常类 定义结构体、命名空间 定义模版、枚举、函数对象 #define 宏定义在C++中用于定义常量、函数、条件编译、字符串、条件表达式、变量、注释、调试信息

    2024年02月10日
    浏览(45)
  • C语言之#define用法入门详解

    在C语言中,常量是使用频率很高的一个量。常量是指在程序运行过程中,其值不能被改变的量。常量常使用#define来定义。 使用#define定义的常量也称为符号常量,可以提高程序的运行效率。 其常见的用法包括两种,分别是: 第一种语法就是定义符号常量, 例如: 此后直到

    2024年02月10日
    浏览(40)
  • 【C语言】#define 宏定义初步使用

    使用宏定义可以防止出错,提高可移植性,可读性,方便性等。 下面列举了一些成熟软件中常用的宏定义。 重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植: typedef unsigned char boolean; /* Boolean value type. / typedef unsigned long int uint32;

    2024年02月10日
    浏览(40)
  • Verilog中的`define与`if的使用

    一部分代码可能有时候用,有时候不用,为了避免全部编译占用资源,可以使用条件编译语句。 语法          条件编译可以通过Verilog的  `ifdef 和 `ifndef 来实现。 这些可以出现在设计中的任何地方,并且可以相互嵌套。  它通常和预编译指令`define配套使

    2024年02月16日
    浏览(30)
  • define, parameter, localparam, specparam, defpara用法简析

    在Verilog中,parameter既不属于变量范畴也不属于线网范畴,经常用来定义一个标志符代表一个 常量 ,当一个模块被另一个模块引用例化时, 高层模块 可以对 低层模 块的参数值进行改写。这样就允许在编译时将不同的参数传递给多个相同名字的模块,而不用单独为只有参数不

    2024年02月16日
    浏览(37)
  • 「C/C++」C/C++宏定义#define

    ✨博客主页 何曾参静谧的博客 📌文章专栏 「C/C++」C/C++程序设计 📚全部专栏 「UG/NX」NX二次开发 「UG/NX」BlockUI集合 「VS」Visual Studio 「QT」QT5程序设计 「C/C++」C/C++程序设计 「Win」Windows程序设计 「算法」数据结构与算法 「File」数据文件格式 @[TOC](目录) *** # 术语说明 `定义

    2024年02月16日
    浏览(39)
  • 初识C语言中的typedef、define以及Status

    小阿杰最近开始看数据结构啦嘿嘿嘿, 可惜小阿杰C语言功底稀薄,以此篇随笔记录一下我卑微的学习之路/苦涩/苦涩 首先define没啥好说的,在文件开头,定义一个固定不变的值。  然后顺便提一嘴 const(写着博客突然想起来有这么个玩意👉👈) const 叫 常量限定符,一般他出

    2024年02月16日
    浏览(35)
  • 【C语言】预处理详解:#define的各种使用方法

    目录 1.#define定义标识符 1.1赋值 1.2   定义 1.3用更形象的符号来替换一种实现 1.4   加续行符换行 1.5#define定义宏 1.6  #define替换的规则 注意事项 2.#和## 3.带有副作用的宏参数 4.函数和宏的对比 #define定义标识符的用法非常简单 name可以由自己来命名,尽量取一些有意义

    2024年02月15日
    浏览(38)
  • [C语言]关键字解析(二) typedef和#define以及区别

    typedef是type define的缩写,之前看一本书上说,也许这个更应该叫typerename,我个人是比较认同的这个观点的.因为这个只是给 已有的类型重新定义了一个方便使用的别名 ,并没有产生新的数据类型。说直白点typedef就是 类型重命名 在实际应用中typedef主要有如下

    2024年02月10日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包