如何消除全局变量的使用
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;
}
我在嵌入式环境中使用一个简单的 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;
}