Error: L6218E: Undefined symbol, 定义--cpp11之后 C函数指针和C++不兼容问题

本文主要是介绍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++不兼容问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1083596

相关文章

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

C++作用域和标识符查找规则详解

《C++作用域和标识符查找规则详解》在C++中,作用域(Scope)和标识符查找(IdentifierLookup)是理解代码行为的重要概念,本文将详细介绍这些规则,并通过实例来说明它们的工作原理,需... 目录作用域标识符查找规则1. 普通查找(Ordinary Lookup)2. 限定查找(Qualif

Oracle修改端口号之后无法启动的解决方案

《Oracle修改端口号之后无法启动的解决方案》Oracle数据库更改端口后出现监听器无法启动的问题确实较为常见,但并非必然发生,这一问题通常源于​​配置错误或环境冲突​​,而非端口修改本身,以下是系... 目录一、问题根源分析​​​二、保姆级解决方案​​​​步骤1:修正监听器配置文件 (listener.

C/C++ chrono简单使用场景示例详解

《C/C++chrono简单使用场景示例详解》:本文主要介绍C/C++chrono简单使用场景示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录chrono使用场景举例1 输出格式化字符串chrono使用场景China编程举例1 输出格式化字符串示

C++/类与对象/默认成员函数@构造函数的用法

《C++/类与对象/默认成员函数@构造函数的用法》:本文主要介绍C++/类与对象/默认成员函数@构造函数的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录名词概念默认成员函数构造函数概念函数特征显示构造函数隐式构造函数总结名词概念默认构造函数:不用传参就可以

C++类和对象之默认成员函数的使用解读

《C++类和对象之默认成员函数的使用解读》:本文主要介绍C++类和对象之默认成员函数的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、默认成员函数有哪些二、各默认成员函数详解默认构造函数析构函数拷贝构造函数拷贝赋值运算符三、默认成员函数的注意事项总结一

VS配置好Qt环境之后但无法打开ui界面的问题解决

《VS配置好Qt环境之后但无法打开ui界面的问题解决》本文主要介绍了VS配置好Qt环境之后但无法打开ui界面的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 目UKeLvb录找到Qt安装目录中designer.UKeLvBexe的路径找到vs中的解决方案资源

C/C++中OpenCV 矩阵运算的实现

《C/C++中OpenCV矩阵运算的实现》本文主要介绍了C/C++中OpenCV矩阵运算的实现,包括基本算术运算(标量与矩阵)、矩阵乘法、转置、逆矩阵、行列式、迹、范数等操作,感兴趣的可以了解一下... 目录矩阵的创建与初始化创建矩阵访问矩阵元素基本的算术运算 ➕➖✖️➗矩阵与标量运算矩阵与矩阵运算 (逐元

C/C++的OpenCV 进行图像梯度提取的几种实现

《C/C++的OpenCV进行图像梯度提取的几种实现》本文主要介绍了C/C++的OpenCV进行图像梯度提取的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录预www.chinasem.cn备知识1. 图像加载与预处理2. Sobel 算子计算 X 和 Y

C/C++和OpenCV实现调用摄像头

《C/C++和OpenCV实现调用摄像头》本文主要介绍了C/C++和OpenCV实现调用摄像头,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录准备工作1. 打开摄像头2. 读取视频帧3. 显示视频帧4. 释放资源5. 获取和设置摄像头属性