引言

最近研究稚晖君的Holocubic工程碰到该问题,调用自己写的头文件会报错找不到,甚至调用LVGL自带的example都报错。发现CSDN上的文章解决办法都是修改json文件,折腾了很久都无法解决,真G2痛苦。好在最后找到了几个解决办法:

解决办法1:

参考bilibili教程:VScode(PlatfromIO)嵌入式开发(ESP32)(ESP8266)(STM32)_哔哩哔哩_bilibili

每次添加完源文件头文件之后 使用组合键ctrl+shift+p 调出命令行运行如下命令

rebuild intelliSense

rebuild intelliSense

等PlatformIO处理完后重新编译即可通过:

  解决办法2:

自己写的头文件放到根目录下include文件夹中 源文件放到根目录下src中,编译可通过。

但是如果是LVGL提供的example,直接把.c文件(比如lv_example_get_started_1.c)放到src文件夹中将无法通过编译,会一直报错“undefined reference....”(这个是真的巨坑,从半夜两点折腾到四点 难蚌)

还需要把头文件引入,才能通过编译。头文件包含 extern "C" ,用于C C++混合编程的关键句

表明它按照类C的编译和连接规约来编译和连接,而不是C++的编译的连接规约。缺少该句,在编译的Link阶段会一直报错。

参考:C++项目中的extern "C" {} - 吴秦 - 博客园引言在用C++的项目源码中,经常会不可避免的会看到下面的代码:#ifdef __cplusplusextern "C" {#endif/*...*/#ifdef __cplusplhttps://www.cnblogs.com/skynet/archive/2010/07/10/1774964.html

如图,将.c放到src目录,.h放到include目录中。

 (唉毕竟是电子系的,没学过编译原理之类的课 T T 以后总得补上)


lvgl_example.c代码(注意头文件包含部分做了修改):

//include部分做了修改:
//#include "../lv_examples.h"
#include<lvgl.h>
// #if LV_BUILD_EXAMPLES && LV_USE_BTN

static void btn_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * btn = lv_event_get_target(e);
    if(code == LV_EVENT_CLICKED) {
        static uint8_t cnt = 0;
        cnt++;

        /*Get the first child of the button which is the label and change its text*/
        lv_obj_t * label = lv_obj_get_child(btn, 0);
        lv_label_set_text_fmt(label, "Button: %d", cnt);
    }
}

/**
 * Create a button with a label and react on click event.
 */
void lv_example_get_started(void)
{
    lv_obj_t * btn = lv_btn_create(lv_scr_act());     /*Add a button the current screen*/
    lv_obj_set_pos(btn, 10, 10);                            /*Set its position*/
    lv_obj_set_size(btn, 120, 50);                          /*Set its size*/
    lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_ALL, NULL);           /*Assign a callback to the button*/

    lv_obj_t * label = lv_label_create(btn);          /*Add a label to the button*/
    lv_label_set_text(label, "Button");                     /*Set the labels text*/
    lv_obj_center(label);
}

// #endif


 对应的.h文件代码:

/**
 * @file lvgl_example.c
 *
 */

#ifndef LV_EX_GET_STARTED_H
#define LV_EX_GET_STARTED_H

#ifdef __cplusplus
extern "C" {
#endif

/*********************
 *      INCLUDES
 *********************/

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 * GLOBAL PROTOTYPES
 **********************/
void lv_example_get_started(void);
/**********************
 *      MACROS
 **********************/

#ifdef __cplusplus
} /*extern "C"*/
#endif

#endif /*LV_EX_GET_STARTED_H*/

Main.c函数就不贴了,就一句调用。

其他办法:

之前问过一个大佬但是这个办法挺复杂的没做 (纯懒狗

 有个群友建议VSCode调用Arduino IDE来编译,这种高级操作还是太难了。

真有用就点个赞吧亲。以后闲了再更新LVGL8的学习笔记可以关注下。

最有效的办法:

最近在用ESP32+Arduino+PIO做课设,看别人的开源代码学到的。

首先,编译问题,可以通过修改VSCode的c_cpp_properties.json文件解决,但是PlatformIO提示这个文件是自动生成的,不允许修改。到PIO官方文档查看,有一个关键字build_flags可以指定要编译文件的路径,之前做这个项目的时候没看明白官方文档写的什么意思,这回看了别人的项目才明白要这样写:

在platformio.ini文件中添加我们要编译的.c .cpp文件的路径:

build_flags = -DLV_LVGL_H_INCLUDE_SIMPLE
			-I./src/lv_app 
			-I./src/lv_app/font
			-I./src/lv_app/image
			-I./src/lv_drivers/display 
			-I./src/lv_drivers/indev 
			-I./src/network
			-I./src/sdcard

如图所示: 

"./src"表示ini文件所处目录下的src文件夹,项目文件结构如图:

 在添加build_flags之后保存ini文件,并使用方法1提到的rebuild intelliSense命令刷新PIO项目,可见c_cpp_properties.json中已经出现我们之前加入的路径,再次编译即可通过。

没写水文, 要个关注不过分吧- - |||

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐