本文主要是介绍Error: L6218E: Undefined symbol, 定义--cpp11之后 C函数指针和C++不兼容问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
当我们在定义函数中采用函数指针作为参数时,
头文件(,h文件)中, 使用如下代码:
#ifdef __cplusplusextern "C"{
#endif //ESP_Error_t esp8266_sendcmd(const char* cmd, const char* response, uint8_t (*cmd_function)(ESP_MSG_LIST));#ifdef __cplusplus}
#endif // __cplusplus
在.c文件中直接定义函数:
ESP_Error_t esp8266_sendcmd(const char* cmd,const char* response, uint8_t (*cmd_function)(ESP_MSG_LIST)){// .....
}
此时, 如果采用 --cpp11 为定义(一般需要采用这个, Keil工程中才能用C++代码)时, 直接编译会出现如下报错
Error: L6218E: Undefined symbol esp8266_sendcmd (referred from esp8266_driver.o).
即没有识别到对应的函数, 这个是因为, .c 文件中的函数指针仍然是按照
解决办法是在你编写的 .c 文件中, 再单独加入一个 extern “C”{} , 完整代码如下:
(这个是在.c文件中把带函数指针这部分再括起来)
#ifdef __cplusplusextern "C"{
#endif/// @brief send the command, wait for response string /// @param cmd string with command (must end with "\\r\\n")/// @param response string need to check for response (such as "OK")/// @param cmd_function if the response is get, it will call cmd_function and send current ESP_MSG_LIST/// for this function, return 0: execute successfully return 1: execute failed /// @return if return ESP_RES_OK, command executed successfully./// @note data received during cmd execution will be ignored, and ESP_CMD_LIST will always be cleared after executionESP_Error_t esp8266_sendcmd(const char* cmd,const char* response, uint8_t (*cmd_function)(ESP_MSG_LIST)){ESP_Error_t result = ESP_RES_CMD_NO_RESPONSE_ERR;_esp8266_sendstring(cmd);esp_timeout_counter = 0; // reset the counterwhile (esp_timeout_counter < ESP8266_RESPONSE_TIMEOUT + extra_command_timeout){Delay_ms(1);uint8_t res;res = _esp8266_receive_msg_cb(); // 1: try receive msg to CMD List if (res) return ESP_RES_RxBUFFER_FULL; // detect if the buffer is full (if full, try execute command once);// compare the ESP_Cmd_List and response string, for (int i=0; i < ESP_Cmd_List.cmd_buffer_length; i++){if (strcmp(ESP_Cmd_List.cmd_buffer[i], response) == 0) { // if get the response expected uint8_t r1 = 0;if (cmd_function!=NULL) r1 = cmd_function(ESP_Cmd_List); // r1 = 0 execute successfully, or failedif (!r1) result = ESP_RES_OK; else result = ESP_RES_CMD_EXEC_FAIL;_esp8266_clearCmdList(); // after execution, clear the command list return result; }}esp_timeout_counter++;}_esp8266_clearCmdList(); // always clear this buff// timeout error handelingif (esp_timeout_counter >= ESP8266_RESPONSE_TIMEOUT + extra_command_timeout){ esp_timeout_counter = 0;_esp8266_clearRxBuffer();result = ESP_RES_CMD_NO_RESPONSE_ERR;}return result;}#ifdef __cplusplus
}
#endif
编译成功
另外文末也顺便提一下, 我最近在写 STM32 的 ESP8266 的AT 指令驱动代码(用于c8t6, ret6等等), 目前这个工程已经开源到 我的仓库https://github.com/FRIEDparrot/ESP8266_AT_Command_Driver
(虽然目前不是特别完善,但是是一个纯C语言的可扩展和移植能力比较强的库, 也欢迎读者来 star ,使用和贡献代码[doge]).
这一期就到这里了, 之后可能ESP8266写完会专门弄一篇相关的来讲一下。
这篇关于Error: L6218E: Undefined symbol, 定义--cpp11之后 C函数指针和C++不兼容问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!