cpp
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 定义 !
cpp
#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)
cpp
#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定义见上面的代码,继续拆~
cpp
#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 结构体