如何消除全局变量的使用

how to eliminate global variable use

我在嵌入式环境中使用一个简单的 json 库,并试图在我的用户代码中删除一个全局变量。我这里有一个片段试图解释我的情况。

该库有一个函数 libjson_parser,每次需要解析 char 数组时都可以调用该函数。操作完成后,它会将操作结果传递给使用 libjson_callback_register 注册为回调的函数(以下示例中的 json_post_parse)。

因为我有不同类型的 json 数据包要分析,所以我使用了一个全局变量 parsing_config ,它在调用解析器之前设置,以便可以在 json_post_parse函数。

我知道使用全局变量是不受欢迎的,所以我正在寻找摆脱这个全局变量的方法,但不确定该怎么做?

// library functions:
// libjson_callback_register
// libjson_parser

// user function, function signature fixed by library:
// json_post_parse

static uint8_t parsing_config = 0;

int main()
{
    // register callback
    libjson_callback_register(json_post_parse);

    // dummy load
    char[32] payload;
    uint16_t len = 32;

    // type A post parsing
    parsing_config = 1;
    libjson_parser(payload, len);

    // type B
    parsing_config = 2;
    libjson_parser(payload, len);


    return 0;
}


json_post_parse(json_obj* json)
{
    switch(parsing_config) {
        case 1:
        //do something
        break;

        case 2:
        // do something
        break;

        default:
        break;
    }
}
// library functions:
// libjson_callback_register
// libjson_parser

// user function, function signature fixed by library:
// json_post_parse


int main()
{
    // dummy load
    char[32] payload;
    uint16_t len = 32;

    // type A post parsing
    // register callback1
    libjson_callback_register(json_post_parse1);
    libjson_parser(payload, len);

    // type B
    // register callback2
    libjson_callback_register(json_post_parse2);
    libjson_parser(payload, len);


    return 0;
}


json_post_parse1(json_obj* json)
{
  // do something1
}
json_post_parse2(json_obj* json)
{
  // do something2
}

您应该按照@CharlieBurns 的建议动态更改回调,但另一种方法是将静态隐藏在 get/set 函数中:

int main()
{
    // register callback
    libjson_callback_register(json_post_parse);

    // dummy load
    char[32] payload;
    uint16_t len = 32;

    // type A post parsing
    parse_config(1);
    libjson_parser(payload, len);

    // type B
    parse_config(2);
    libjson_parser(payload, len);


    return 0;
}


uint8_t parse_config( uint8_t config )
{
    static uint8_t parsing_config = 0;
    if( parse_config != 0 )
    {
        parsing_config = config ;
    }

    return parsing_config ;
}


void json_post_parse(json_obj* json)
{
    switch( parse_config(0) ) 
    {
        ...
    }
}

或者(更传统地)您可以将 json_post_parse(json_obj* json) 放在一个单独的带有 public setter 函数的翻译单元中。该变量仍然具有文件范围,但它只对那些有业务访问它的函数可见。文件作用域不是全局作用域,只要变量对不需要查看它的函数不可见,就可以避免与全局变量相关的问题。所以:

json_parse_callback.c

static uint8_t parsing_config = 0;

void parse_set_config( uint8_t config )
{
    parsing_config = config ;
}


void json_post_parse(json_obj* json)
{
    switch( parsing_config  ) 
    {
        ...
    }
}

json_parse_callback.h

#if !defined json_parse_callback_h
#define json_parse_callback_h

void parse_set_config( uint8_t config ) ;
void json_post_parse(json_obj* json) ;

#endif

main.c

int main()
{
    // register callback
    libjson_callback_register(json_post_parse);

    // dummy load
    char[32] payload;
    uint16_t len = 32;

    // type A post parsing
    parse_set_config(1);
    libjson_parser(payload, len);

    // type B
    parse_set_config(2);
    libjson_parser(payload, len);


    return 0;
}