#define MACRO_NAME(para) do{macro content}while(0)

本文探讨了使用do{}
#define MACRO_NAME(para) do{macro content}while(0)

 

的格式,总结了以下几个原因:

 

 

 

1,空的宏定义避免warning:

 

#define foo() do{}while(0)

 

 

 

2,存在一个独立的block,可以用来进行变量定义,进行比较复杂的实现。

 

 

 

3,如果出现在判断语句过后的宏,这样可以保证作为一个整体来是实现:

 

#define foo(x) /

 

action1(); /

 

action2();

 

在以下情况下:

 

if(NULL == pPointer)

 

   foo();

 

就会出现action1和action2不会同时被执行的情况,而这显然不是程序设计的目的。

 

 

 

4,以上的第3种情况用单独的{}也可以实现,但是为什么一定要一个do{}while(0)呢,看以下代码:

 

#define switch(x,y) {int tmp; tmp=x;x=y;y=tmp;}

 

if(x>y)

 

switch(x,y);

 

else       //error, parse error before else

 

otheraction();

 

 

 

在把宏引入代码中,会多出一个分号,从而会报错。
 
//------------------------------------------------
使用do{….}while(0) 把它包裹起来,成为一个独立的语法单元,
从而不会与上下文发生混淆。同时因为绝大多数的编译器都能够识别do{…}while(0)这种无
用的循环并进行优化,所以使用这种方法也不会导致程序的性能降低。

 

/* *MQTT 数据库存储MQTT未发布消息的表头格式 *id(INTEGER) | timestamp(DATETIME) | sent_flag(INTEGER) | topic(TEXT) | payload(TEXT) *id:用于唯一标识 *timestamp:时间戳用于记录存储时间 *pub:用于标记是否完成MQTT补发(0:未发布;1:已发布) *topic:存储的MQTT的主题 *payload:存储的MQTT的Payload内容 */ /*=========================================================================== include files ===/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sqlite3.h> #include <stdbool.h> #include <time.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <dirent.h> #include <pthread.h> #include “mqtt.h” #include “uart_command.h” #include “…/platform/queue_buffer.h” #include “…/bms_info_data/bms_info_data.h” #include “…/platform/syslog/logger.h” / Macro Definition ========================================================================/ #define MQTT_PUB_DB_MAX_QUEUE_LIMIT 3 #define MQTT_PUB_DB_DIR “/opt/database/” #define MQTT_PUB_DB_NAME “/opt/database/mqtt_pub_history.db” #define MQTT_PUB_TABLE_CREATE_SQL “CREATE TABLE IF NOT EXISTS mqtt_pub_msg (id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp text,sent_flag INTEGER DEFAULT 0, topic TEXT, payload TEXT);” #define MQTT_PUB_MSG_INSERT_SQL “INSERT INTO mqtt_pub_msg (timestamp, topic, payload) VALUES (?, ?, ?);” #define MQTT_PUB_SELECT_OLDEST_UNSENT_MSG_SQL “SELECT id, timestamp, sent_flag, topic FROM mqtt_pub_msg WHERE sent_flag = 0 ORDER BY timestamp ASC LIMIT 1;” #define MQTT_PUB_UPDATE_OLDEST_UNSENT_FLAG_SQL “UPDATE mqtt_pub_msg SET sent_flag = 1 WHERE id = ? AND topic = ?;” #define MQTT_PUB_DROP_TABLE_SQL “DROP TABLE IF EXISTS mqtt_pub_msg;VACUUM;” /*======================================================================== Enumeration Definition ========================================================================/ /*======================================================================== Type Definition =========================================================================/ /*======================================================================== Global Variable ========================================================================/ static sqlite3 * mqtt_pub_db = NULL; static bool db_initialized = false; static pthread_mutex_t mqtt_pub_db_mutex = PTHREAD_MUTEX_INITIALIZER; QueueList mqtt_db_store_queue = {0}; pthread_mutex_t mqtt_db_store_queue_mutex = PTHREAD_MUTEX_INITIALIZER; /*======================================================================== function Definition ========================================================================/ bool mqtt_pub_db_initialized(void){ return db_initialized; } int mqtt_pub_db_dir_create(void) { int ret = 0; DIR *dir = NULL; if(NULL == (dir = opendir(MQTT_PUB_DB_DIR))){ if (0 != (ret = mkdir(MQTT_PUB_DB_DIR,0777))){ LOG(LOG_ERR,“mkdir %s failed!,ret:%d!\n”,MQTT_PUB_DB_DIR,ret); } } if(NULL != dir){ closedir(dir); dir = NULL; } return ret; } // Initialize the SQLite database. int mqtt_pub_db_init(void) { char *err_msg = NULL; int rc = sqlite3_open(MQTT_PUB_DB_NAME, &mqtt_pub_db); if (rc) { LOG(LOG_ERR,“Can’t open database: %s\n”, sqlite3_errmsg(mqtt_pub_db)); return rc; } else { LOG(LOG_ERR,“Opened mqtt pub database successfully\n”); } rc = sqlite3_exec(mqtt_pub_db, MQTT_PUB_TABLE_CREATE_SQL, 0, 0, &err_msg); if (rc != SQLITE_OK) { LOG(LOG_ERR,"SQL error: %s\n", err_msg); sqlite3_free(err_msg); sqlite3_close(mqtt_pub_db); return rc; } else { if (NULL != err_msg){ sqlite3_free(err_msg); err_msg = NULL; } LOG(LOG_DEBUG,"Table created successfully\n"); db_initialized = 1; } return 0; } //-- 彻底删除表(含自增ID重置) //DROP TABLE IF EXISTS mqtt_pub_msg; //CREATE TABLE IF NOT EXISTS mqtt_pub_msg (); – 原建表语句 int mqtt_pub_db_drop_and_create_table(void) { char *err_msg = NULL; int rc = 0; if (1 != db_initialized) { LOG(LOG_ERR,“db_initialized error!\n”); return -1; } if (NULL == mqtt_pub_db){ LOG(LOG_ERR,“mqtt db handle is NULL!\n”); return -1; } pthread_mutex_lock(&mqtt_pub_db_mutex); db_initialized = false; rc = sqlite3_exec(mqtt_pub_db, MQTT_PUB_DROP_TABLE_SQL, 0, 0, &err_msg); if (rc != SQLITE_OK) { LOG(LOG_ERR,“SQL error: %s\n”, err_msg); sqlite3_free(err_msg); err_msg = NULL; sqlite3_close(mqtt_pub_db); pthread_mutex_unlock(&mqtt_pub_db_mutex); return rc; } else { if (NULL != err_msg){ sqlite3_free(err_msg); err_msg = NULL; } LOG(LOG_DEBUG,“Drop Table successfully\n”); } rc = sqlite3_exec(mqtt_pub_db, MQTT_PUB_TABLE_CREATE_SQL, 0, 0, &err_msg); if (rc != SQLITE_OK) { LOG(LOG_ERR,"SQL error: %s\n", err_msg); sqlite3_free(err_msg); sqlite3_close(mqtt_pub_db); pthread_mutex_unlock(&mqtt_pub_db_mutex); return rc; } else { if (NULL != err_msg){ sqlite3_free(err_msg); err_msg = NULL; } LOG(LOG_DEBUG,"Table created successfully\n"); db_initialized = 1; } pthread_mutex_unlock(&mqtt_pub_db_mutex); return 0; } /* table name:mqtt_pub_msg table header:id(INTEGER) | timestamp(DATETIME) | sent_flag(INTEGER) | topic(TEXT) | payload(TEXT) */ // Store a message in the SQLite database. int mqtt_pub_db_msg_store(const char *topic, const char *message) { int ret = 0; sqlite3_stmt *stmt; const char sql = MQTT_PUB_MSG_INSERT_SQL; time_t now = time(NULL); struct tm local_buf; struct tm * local = localtime_r(&now,&local_buf); char timestamp[64] = {0}; strftime(timestamp, sizeof(timestamp), “%Y-%m-%d %H:%M:%S”, local); if ((NULL == topic) || (NULL == message)){ LOG(LOG_ERR,“param pointer is NULL!\n”); return -1; } if (!db_initialized) { LOG(LOG_ERR,“db_initialized error!\n”); return -1; } pthread_mutex_lock(&mqtt_pub_db_mutex); if ((NULL != strstr(topic,MQTT_PUB_TOPIC_SUFFIX_SYS)) || (NULL != strstr(topic,MQTT_PUB_TOPIC_SUFFIX_PCS)) || (NULL != strstr(topic,MQTT_PUB_TOPIC_SUFFIX_BMS)) || (NULL != strstr(topic,MQTT_PUB_TOPIC_SUFFIX_CHR)) || (NULL != strstr(topic,MQTT_PUB_TOPIC_SUFFIX_AIR)) || (NULL != strstr(topic,MQTT_PUB_TOPIC_SUFFIX_FPE)) || (NULL != strstr(topic,MQTT_PUB_TOPIC_SUFFIX_IO)) || (NULL != strstr(topic,MQTT_PUB_TOPIC_SUFFIX_DG)) || (NULL != strstr(topic,MQTT_PUB_TOPIC_SUFFIX_LTE))|| (NULL != strstr(topic,MQTT_PUB_TOPIC_SUFFIX_PV))) { LOG(LOG_DEBUG,“topic:%s pub storage to database!\n”,topic); sqlite3_prepare_v2(mqtt_pub_db, sql, -1, &stmt, NULL); /sqlite3_stmt:准备好的语句对象/ sqlite3_bind_text(stmt, 1, timestamp, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 2, topic, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 3, message, -1, SQLITE_STATIC); if (sqlite3_step(stmt) != SQLITE_DONE) { LOG(LOG_ERR,"SQL error: %s\n", sqlite3_errmsg(mqtt_pub_db)); ret = -1; } sqlite3_finalize(stmt);/*使用sqlite3_prepare_v2准备语句对象,在使用完成后要调用sqlite3_finalize释放资源*/ } pthread_mutex_unlock(&mqtt_pub_db_mutex); return ret; } /删除超出指定时间范围的数据。例如,删除早于 7 天前的数据/ void mqtt_pub_db_delete_old_data(sqlite3 *db, int days) { char sql[256]; time_t now = time(NULL); struct tm local_buf; struct tm *local = localtime_r(&now,&local_buf); char datetime[64]; if (NULL == db){ LOG(LOG_ERR,“db pointer is NULL!\n”); return; } if (!db_initialized) { LOG(LOG_ERR,“db_initialized error!\n”); return; } strftime(datetime, sizeof(datetime), “%Y-%m-%d %H:%M:%S”, local); // Calculate the date and time for the cutoff local->tm_mday -= days; mktime(local); // Normalize the time struct strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", local); snprintf(sql, sizeof(sql), "DELETE FROM mqtt_pub_msg WHERE timestamp < '%s';", datetime); char *errmsg = NULL; int rc = sqlite3_exec(db, sql, 0, 0, &errmsg); if (rc != SQLITE_OK) { LOG(LOG_ERR,"SQL error: %s\n", errmsg); sqlite3_free(errmsg); } else { if (NULL != errmsg){ sqlite3_free(errmsg); errmsg = NULL; } LOG(LOG_DEBUG,"Old data deleted successfully\n"); } } void mqtt_pub_db_send_cmd(long id,const unsigned char * topic) { module_mqtt_topic_pub_db_cmd_info_t mqtt_pub_db_cmd_info = {0}; if (NULL == topic){ fprintf(stderr, “topic is NULL!”); return; } memset(&mqtt_pub_db_cmd_info,0x00,sizeof(module_mqtt_topic_pub_db_cmd_info_t)); mqtt_pub_db_cmd_info.mqtt_pub_msg_db_id = id; strcpy(mqtt_pub_db_cmd_info.mqtt_pub_msg_db_topic,(char*)topic); send_module_cmd_data(STAT_SET_MQTT_PUB_DB,(uint8_t*)&mqtt_pub_db_cmd_info,sizeof(module_mqtt_topic_pub_db_cmd_info_t)); return; } /* table name:mqtt_pub_msg table header:id(INTEGER) | timestamp(DATETIME) | sent_flag(INTEGER) | topic(TEXT) | payload(TEXT) */ // Resend the oldest message from the database. int mqtt_db_send_oldest_msg_cmd(void) { sqlite3_stmt *stmt; const char *sql = MQTT_PUB_SELECT_OLDEST_UNSENT_MSG_SQL; //printf(“enter into %s,db_initialized:%d\n”,func,db_initialized); if (!db_initialized) { LOG(LOG_ERR,“db_initialized error!\n”); return -1; } //printf(“%s db_initialized!\n”,func); pthread_mutex_lock(&mqtt_pub_db_mutex); if (sqlite3_prepare_v2(mqtt_pub_db, sql, -1, &stmt, NULL) != SQLITE_OK){ LOG(LOG_ERR,“Failed to prepare SELECT statement\n”); pthread_mutex_unlock(&mqtt_pub_db_mutex); return -1; } while (sqlite3_step(stmt) == SQLITE_ROW) { long id = sqlite3_column_int64(stmt, 0); const unsigned char *timestamp = sqlite3_column_text(stmt, 1); const unsigned char *topic = sqlite3_column_text(stmt, 3); LOG(LOG_DEBUG,"history mqtt pub msg send:id:[%ld] timestamp:[%s] topic:[%s]\n",id,timestamp,topic); mqtt_pub_db_send_cmd(id,topic); break; } sqlite3_finalize(stmt); pthread_mutex_unlock(&mqtt_pub_db_mutex); return 0; } int mqtt_db_send_msg_by_id_topic(long id,char * topic,char ** dst_str,uint16_t * dst_len) { int ret = 0; char *query = “SELECT payload FROM mqtt_pub_msg WHERE id = ? AND topic = ? AND sent_flag = 0;”; sqlite3_stmt *stmt; if(NULL == topic){ LOG(LOG_ERR,“topic is NULL!\n”); return -1; } if (!db_initialized) { LOG(LOG_ERR,“db_initialized error!\n”); return -1; } pthread_mutex_lock(&mqtt_pub_db_mutex); // Prepare the SELECT statement if (sqlite3_prepare_v2(mqtt_pub_db, query, -1, &stmt, NULL) != SQLITE_OK) { LOG(LOG_ERR,“Failed to prepare SELECT statement\n”); pthread_mutex_unlock(&mqtt_pub_db_mutex); return -1; } // Bind the id to the SELECT statement sqlite3_bind_int64(stmt, 1, id); sqlite3_bind_text(stmt, 2, topic, -1, SQLITE_STATIC); // Execute the SELECT statement if (sqlite3_step(stmt) == SQLITE_ROW) { const unsigned char *payload = sqlite3_column_text(stmt, 0); int payload_len = sqlite3_column_bytes(stmt, 0); if (NULL == (dst_str = (char)calloc(1,payload_len+1))){ ret = -1; *dst_len = 0; }else { memcpy(*dst_str,payload,payload_len); *dst_len = (uint16_t)payload_len; ret = 0; } } else { LOG(LOG_ERR,“No record found with id %ld\n”, id); sqlite3_finalize(stmt); pthread_mutex_unlock(&mqtt_pub_db_mutex); return -1; } // Finalize the SELECT statement sqlite3_finalize(stmt); pthread_mutex_unlock(&mqtt_pub_db_mutex); return ret; } void mqtt_db_query_and_update_sent_flag(long id,char * topic) { char *query = “SELECT sent_flag FROM mqtt_pub_msg WHERE id = ? AND topic = ?;”; char *update_query = “UPDATE mqtt_pub_msg SET sent_flag = 1 WHERE id = ? AND topic = ?;”; sqlite3_stmt *stmt; sqlite3_stmt *update_stmt; int sent_flag = 0; if(NULL == topic){ LOG(LOG_ERR,"topic is NULL!\n"); return; } if (!db_initialized) { LOG(LOG_ERR,"db_initialized error!\n"); return; } pthread_mutex_lock(&mqtt_pub_db_mutex); // Prepare the SELECT statement if (sqlite3_prepare_v2(mqtt_pub_db, query, -1, &stmt, NULL) != SQLITE_OK) { pthread_mutex_unlock(&mqtt_pub_db_mutex); LOG(LOG_ERR,"Failed to prepare SELECT statement\n"); return; } // Bind the id to the SELECT statement sqlite3_bind_int64(stmt, 1, id); sqlite3_bind_text(stmt, 2, topic, -1, SQLITE_STATIC); // Execute the SELECT statement if (sqlite3_step(stmt) == SQLITE_ROW) { sent_flag = sqlite3_column_int(stmt, 0); } else { LOG(LOG_ERR,"No record found with id %ld\n", id); sqlite3_finalize(stmt); pthread_mutex_unlock(&mqtt_pub_db_mutex); return; } // Finalize the SELECT statement sqlite3_finalize(stmt); // Check the sent_flag value if (sent_flag == 0) { // Prepare the UPDATE statement if (sqlite3_prepare_v2(mqtt_pub_db, update_query, -1, &update_stmt, NULL) != SQLITE_OK) { LOG(LOG_ERR,"Failed to prepare UPDATE statement\n"); pthread_mutex_unlock(&mqtt_pub_db_mutex); return; } // Bind the message_id to the UPDATE statement sqlite3_bind_int64(update_stmt, 1, id); sqlite3_bind_text(stmt, 2, topic, -1, SQLITE_STATIC); // Execute the UPDATE statement if (sqlite3_step(update_stmt) != SQLITE_DONE) { LOG(LOG_ERR,"Failed to update sent_flag for id %ld\n", id); } // Finalize the UPDATE statement sqlite3_finalize(update_stmt); LOG(LOG_DEBUG,"Successfully updated sent_flag for message id %ld\n", id); } else { LOG(LOG_DEBUG,"Message id %ld has already been sent\n", id); } pthread_mutex_unlock(&mqtt_pub_db_mutex); } // Resend the oldest message from the database. int mqtt_db_oldest_msg_send_cmd(void) { if (!db_initialized) { fprintf(stderr, “%s db_initialized error!\n”,func); return -1; } sqlite3_stmt *stmt; const char *sql = MQTT_PUB_SELECT_OLDEST_UNSENT_MSG_SQL; pthread_mutex_lock(&mqtt_pub_db_mutex); sqlite3_prepare_v2(mqtt_pub_db, sql, -1, &stmt, NULL); while (sqlite3_step(stmt) == SQLITE_ROW) { long id = sqlite3_column_int64(stmt, 0); const unsigned char * datetime = sqlite3_column_text(stmt, 1); int sent_flag = sqlite3_column_int(stmt, 2); const unsigned char *topic = sqlite3_column_text(stmt, 3); const unsigned char *message = sqlite3_column_text(stmt, 4); LOG(LOG_DEBUG,"history mqtt pub msg:id:[%ld] datatime:[%s] sent_flag:[%d] topic:[%s] payload:[%s]\n",id,datetime,sent_flag,topic,message); mqtt_pub_db_send_cmd(id,topic); break; } sqlite3_finalize(stmt); pthread_mutex_unlock(&mqtt_pub_db_mutex); return 0; } void * mqtt_pub_db_process_thread_entry(void * arg) { int ret = 0; unsigned int count = 0; int module_cmd_queue_num = 0; ec600u_mqtt_client_connect_state_t mqtt_cli_conn_state = {0}; OtherDevInfo_Core2Core other_dev_info = {0}; memset(&other_dev_info,0x00,sizeof(OtherDevInfo_Core2Core)); ret = mqtt_pub_db_dir_create(); if (0 != ret){ LOG(LOG_ERR,“create directory %s err!”,MQTT_PUB_DB_DIR); goto exit_mqtt_pub_db_process_thread; } //sqlite3_config(SQLITE_CONFIG_MULTITHREAD);//设置SQLite为多线程模式 sqlite3_config(SQLITE_CONFIG_SERIALIZED); // 设置为串行数据库 ret = mqtt_pub_db_init(); if (0 != ret){ LOG(LOG_ERR,"create database:%s err!",MQTT_PUB_DB_NAME); goto exit_mqtt_pub_db_process_thread; } while(1){ if (count % 1 == 0){ get_module_mqtt_cli_conn_state(&mqtt_cli_conn_state); if (1 == mqtt_cli_conn_state.mqtt_connect_state){ module_cmd_queue_num = get_module_cmd_queue_num(); if (module_cmd_queue_num <= MQTT_PUB_DB_MAX_QUEUE_LIMIT){ /*发送历史数据*/ mqtt_db_send_oldest_msg_cmd(); } } } if (count % 60 == 0){ //1分钟检测一次并删除超出7天的历史数据 count = 0; /*删除7天前的历史数据*/ pthread_mutex_lock(&mqtt_pub_db_mutex); mqtt_pub_db_delete_old_data(mqtt_pub_db,7); pthread_mutex_unlock(&mqtt_pub_db_mutex); } get_r_core_R2A_OtherDev_info(&other_dev_info); if (0x5A == other_dev_info.data[910]){ /*Offset 910 for clean mqtt*/ mqtt_pub_db_drop_and_create_table(); } count++; sleep(1); } exit_mqtt_pub_db_process_thread: LOG(LOG_ERR,“exit”); sqlite3_close(mqtt_pub_db); pthread_exit(NULL); } int cmd_prot_msg_pack(uint8_t *data,uint16_t data_len,module_cmd_type_e cmd_type,uint8_t * output,uint32_t *output_len) { module_cmd_prot_t cmd_prot_info = {0}; if (NULL == output) return -1; //printf(“Enter into %s func\n”,func); memset(&cmd_prot_info, 0, sizeof(module_cmd_prot_t)); cmd_prot_info.cmd_type = cmd_type; cmd_prot_info.data_len = data_len; memcpy(output, &cmd_prot_info, MODULE_CMD_PROT_HEAD_LEN); if ((data != NULL) && (data_len > 0)) { memcpy(output + MODULE_CMD_PROT_HEAD_LEN, data, data_len); } *output_len = MODULE_CMD_PROT_HEAD_LEN + data_len; return 0; } int mqtt_offline_db_store_enqueue(void *ctx) { int ret = 0; ligoo_msg_info_s *info = (ligoo_msg_info_s *)ctx; ligoo_msg_info_s msg_info = {0}; msg_info.data = info->data; msg_info.data_len = info->data_len; LOG(LOG_DEBUG,"Enter into %s,module_cmd_queue num:%d\n",__func__,num_queue(&mqtt_db_store_queue)); pthread_mutex_lock(&mqtt_db_store_queue_mutex); if (0 != enqueue(msg_info.data,msg_info.data_len , &mqtt_db_store_queue)) { LOG(LOG_ERR,"enqueue failed!\n"); ret = -1; } if (NULL != msg_info.data){ free(msg_info.data); } pthread_mutex_unlock(&mqtt_db_store_queue_mutex); return ret; } /* *input para1:unsigned char * data *input para2:unsigned int data_len *input para3:unsigned char cmd_type * *return param:int */ int mqtt_offline_db_store_cmd_data(module_cmd_type_e cmd_type,unsigned char * data,unsigned int data_len) { int ret = 0; ligoo_msg_info_s msg_info ={0}; msg_info.data_len = data_len + MODULE_CMD_PROT_HEAD_LEN; msg_info.data = (unsigned char )calloc(1,msg_info.data_len); cmd_prot_msg_pack(data,data_len,cmd_type,msg_info.data,&msg_info.data_len); ret = mqtt_offline_db_store_enqueue((void)&msg_info); return ret; } void * mqtt_pub_db_db_store_process_thread_entry(void * arg) { int ret =0; ligoo_msg_info_s msg_info = {0}; module_cmd_prot_t module_cmd_prot_info = {0}; char * payload_json_object = NULL; uint16_t payload_json_object_len = 0; ligoo_mqtt_pub_send_topic_t mqtt_pub_send_topic = {0}; module_mqtt_topic_pub_cmd_info_t module_mqtt_topic_pub_cmd_info = {0}; ec600u_mqtt_client_connect_state_t mqtt_cli_conn_state = {0}; module_mqtt_topic_pub_info_t module_mqtt_topic_pub_info = {0}; LOG(LOG_DEBUG,“Enter\n”); init_queue(&mqtt_db_store_queue); while(1) { if(is_empty(&mqtt_db_store_queue)) { usleep(100000); continue; } memset(&msg_info,0x00,sizeof(ligoo_msg_info_s)); memset(&module_cmd_prot_info,0x00,sizeof(module_cmd_prot_t)); if (NULL != (msg_info.data = get_head(&mqtt_db_store_queue))) { if ((msg_info.data_len = get_head_len(&mqtt_db_store_queue)) < 0) { pthread_mutex_lock(&mqtt_db_store_queue_mutex); dequeue(&mqtt_db_store_queue); pthread_mutex_unlock(&mqtt_db_store_queue_mutex); continue; } memcpy(&module_cmd_prot_info,msg_info.data,MODULE_CMD_PROT_HEAD_LEN); if (msg_info.data_len == module_cmd_prot_info.data_len + MODULE_CMD_PROT_HEAD_LEN){ module_cmd_prot_info.data = msg_info.data + MODULE_CMD_PROT_HEAD_LEN; }else { pthread_mutex_lock(&mqtt_db_store_queue_mutex); dequeue(&mqtt_db_store_queue); pthread_mutex_unlock(&mqtt_db_store_queue_mutex); continue; } LOG(LOG_DEBUG,“process module cmd:%d\n”,module_cmd_prot_info.cmd_type); switch(module_cmd_prot_info.cmd_type){ case STAT_SET_MQTT_PUB:{ memset(&module_mqtt_topic_pub_cmd_info,0x00,sizeof(module_mqtt_topic_pub_cmd_info_t)); memset(&module_mqtt_topic_pub_info,0x00,sizeof(module_mqtt_topic_pub_info_t)); memset(&mqtt_pub_send_topic,0x00,sizeof(ligoo_mqtt_pub_send_topic_t)); if (module_cmd_prot_info.data_len == sizeof(module_mqtt_topic_pub_cmd_info_t)){ memcpy(&module_mqtt_topic_pub_cmd_info,module_cmd_prot_info.data,module_cmd_prot_info.data_len); }else { break; } ret = get_mqtt_topic_pub_info_cb_process(module_mqtt_topic_pub_cmd_info.param_id,module_mqtt_topic_pub_cmd_info.topic_suffix,&module_mqtt_topic_pub_info); if (0 == ret){ mqtt_pub_send_topic.qos = module_mqtt_topic_pub_info.qos; get_mqtt_pub_topic_prefix(mqtt_pub_send_topic.topic,MQTT_TOPIC_CONTAIN_MAX_LEN); strcat(mqtt_pub_send_topic.topic,module_mqtt_topic_pub_info.topic_suffix); LOG(LOG_DEBUG,“mqtt pub topic:%s\n”,mqtt_pub_send_topic.topic); mqtt_pub_send_topic.topic_len = strlen(mqtt_pub_send_topic.topic); payload_json_object = module_mqtt_topic_pub_info.pub_payload_json_cb(module_mqtt_topic_pub_cmd_info.param_id); if (NULL == payload_json_object){ LOG(LOG_DEBUG,“payload_json_object is NULL!\n”); break; } payload_json_object_len = strlen(payload_json_object); LOG(LOG_DEBUG,“mqtt pub topic payload:[%s] payload len:[%d]\n”,payload_json_object,payload_json_object_len); get_module_mqtt_cli_conn_state(&mqtt_cli_conn_state); LOG(LOG_DEBUG,“mqtt broker disconnected:%d!store into db!\n”,mqtt_cli_conn_state.mqtt_connect_state); mqtt_pub_db_msg_store(mqtt_pub_send_topic.topic,payload_json_object); if(payload_json_object){ free(payload_json_object); payload_json_object = NULL; } break; } break; } default:{ break; } } } pthread_mutex_lock(&mqtt_db_store_queue_mutex); dequeue(&mqtt_db_store_queue); pthread_mutex_unlock(&mqtt_db_store_queue_mutex); } pthread_exit(NULL); } 请分析以上代码是否存在内存泄露问题?如果内存请指出对应代码位置,并给出修改方案。
07-12
这段代码是 C/C++ 中的宏定义,使用了宏展开和字符串化的技巧。我们逐步解释其含义和作用。 --- ### 一、宏定义部分 ```c #ifndef MACRO_TO_STR #define _MACRO_TO_STR(x) #x #define MACRO_TO_STR(x) _MACRO_TO_STR(x) #endif ``` #### 1. `#x` 的作用: - 在宏定义中,`#x` 表示将参数 `x` 转换为字符串。这是宏中的“字符串化”操作符。 - 例如: ```c #define STR(x) #x STR(hello) // 展开为 "hello" STR(123) // 展开为 "123" ``` #### 2. `_MACRO_TO_STR(x)`: - 这是一个辅助宏,用于将参数 `x` 字符串化。 #### 3. `MACRO_TO_STR(x)`: - 这是一个“间接宏”,它调用 `_MACRO_TO_STR(x)`,目的是确保参数 `x` 被完全展开后再进行字符串化。 #### 为什么需要两层宏? - 如果直接使用 `#x`,传入的是另一个宏名时,它不会展开,而是直接变成字符串。 - 通过两层宏,先让 `x` 被预处理器展开,再字符串化。 ✅ 示例: ```c #define VALUE 123 #define STR(x) #x #define XSTR(x) STR(x) XSTR(VALUE) // 展开为 "123" STR(VALUE) // 展开为 "VALUE" ``` --- ### 二、使用宏的地方 ```c #define EXCLUDE_WAN MACRO_TO_STR(INCLUDE_REAL_NAME_EWAN) ``` #### 含义: - `INCLUDE_REAL_NAME_EWAN` 是一个宏或标识符。 - `MACRO_TO_STR(...)` 会先展开 `INCLUDE_REAL_NAME_EWAN`,然后将其转换为字符串。 #### 举例说明: 假设: ```c #define INCLUDE_REAL_NAME_EWAN ewan_real ``` 那么: ```c EXCLUDE_WAN // 会被展开为 "ewan_real" ``` --- ### 三、总结 | 宏定义 | 作用说明 | |---------------------|----------| | `_MACRO_TO_STR(x)` | 将 `x` 转换为字符串 | | `MACRO_TO_STR(x)` | 先展开 `x`,再转换为字符串 | | `EXCLUDE_WAN` | 展开为 `INCLUDE_REAL_NAME_EWAN` 的字符串形式 | --- ### 四、实际用途 这种技巧常用于: - 日志输出宏中打印宏值 - 构建配置字符串 - 调试信息输出 - 自动生成配置相关的字符串常量 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值