【问题标题】:Error passing instances to library functions将实例传递给库函数时出错
【发布时间】:2022-01-13 11:59:35
【问题描述】:

我遇到了指针问题。 我正在尝试使用 MCUFRIEND_kbv TFT 库创建自定义触摸键盘库。 当我尝试将 TFT 实例的指针(在 main.cpp 中作为 tft 变量找到)传递给键盘库的 drawKeys 函数(在 main.cpp 的 loop() 中调用为 kb.drawKeys(&tft))我得到一个错误

.pio\build\esp32doit-devkit-v1\src\main.cpp.o:(.literal._Z4loopv+0x4): undefined reference to `Keyboard::drawKeys(MCUFRIEND_kbv*)'
.pio\build\esp32doit-devkit-v1\src\main.cpp.o: In function `loop()':
Filepath/src/main.cpp:140: undefined reference to `Keyboard::drawKeys(MCUFRIEND_kbv*)'

“main.cpp”文件

//INCLUDES
#include <SPI.h>
#include "Adafruit_GFX.h"
#include <MCUFRIEND_kbv.h>
#include <Wire.h>
#include "Fonts/FreeSerif24pt7b.h"
#include <SD.h>
#include "Keyboard.h"
 
//TFT
MCUFRIEND_kbv tft;
 
//KeyBoard & Buttons configuration
#define XELEMENTS 13
#define YELEMENTS 3
#define BUTTONMARGINS 1
#define SIDEPADDING 6
int _width = round(tft.width()/XELEMENTS)-(2*BUTTONMARGINS);
int _height = _width;
Keyboard kb(_height, _width, YELEMENTS, XELEMENTS, BUTTONMARGINS, SIDEPADDING);
 
bool sd_init = false;
void setup()
{
    Serial.begin(250000);
    Serial.println(F("TFT LCD test"));
    pinMode(27, INPUT);
    pinMode(22, OUTPUT);
    Serial.print("TFT size is ");
    Serial.print(tft.width());
    Serial.print("x");
    Serial.println(tft.height());
    tft.reset();
    Serial.print("ID: ");
    Serial.println(tft.readID(), HEX);
    uint16_t identifier = 0x9486;
    tft.begin(identifier);
    tft.fillScreen(TFT_BLACK);
    tft.setRotation(3);
    if (SD.begin(5))
    {
        sd_init = true;
    }
    tft.fillRect(0, 0, 480, 320, TFT_BLACK);
   
}
void loop(void)
{
    while(1)
    {
        //tft.setFont(&FreeSerif24pt7b);
        tft.fillRect(0,50,480,100, TFT_BLACK);
        kb.drawKeys(&tft);
        delay(2000);
    }
}

“Keyboard.h”文件

#ifndef _KEYBOARD_H
#define _KEYBOARD_H
 
#include "Adafruit_GFX.h"
#include <MCUFRIEND_kbv.h>
 
class Keyboard {
    private:
 
    public:
        Keyboard(short _h, short _w, short _yel, short _xel, short _bmargins, short _sidepad);
        void drawKeys(MCUFRIEND_kbv* _tft);
};
#endif

“Keyboard.cpp”文件

#include "Keyboard.h"
#include "MCUFRIEND_kbv.h"
#include "Adafruit_GFX.h"
 
short xEl = 0, yEl = 0, bMargins = 0, sidePadding = 0, width = 0, height = 0;
unsigned short bBorder = 0, bBackground = 0, bTextColor = 0;
 
const char Mobile_KB[3][13] PROGMEM = {
{0, 13, 10, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'},
{2, 11, 9, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'},
{2, 11, 7, 'Z', 'X', 'C', 'V', 'B', 'N', 'M'},
};
 
const char Mobile_NumKeys[3][13] PROGMEM = {
{0, 13, 10, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'},
{2, 11, 9, '-', '/', ':', ';', '(', ')', '&', '@', '"'},
{2, 11, 7, '.', ',', '?', '!', '\'', '`', '$'}
};
 
const char Mobile_SymKeys[3][13] PROGMEM = {
{0, 13, 10, '[', ']', '{', '}', '#', '%', '^', '*', '+', '='},
{2, 11, 9, '_', '\\', '|', '~', '<', '>', '$', '"', '&'}, //4
{2, 11, 7, '.', ',', '?', '!', '\'', '`', '@'}
};
 
Keyboard::Keyboard(short _h, short _w, short _yel, short _xel, short _bmargins, short _sidepad)
{
    height = _h;
    width = _w;
    yEl = _yel;
    xEl = _xel;
    bMargins = _bmargins;
    sidePadding = _sidepad;
}
 
void drawKeys(MCUFRIEND_kbv &_tft)
{
    int yoffset = height - (height * yEl);
    for (int i = 0; i < yEl; i++)
    {
        for (int x = 0; x < xEl; x++)
        {
            _tft.fillRoundRect(((width*x)+bMargins+sidePadding),(((height*i)+yoffset)+bMargins), width-(2*bMargins), height-(2*bMargins), 8, TFT_DARKCYAN);
            _tft.drawRoundRect(((width*x)+bMargins+sidePadding),(((height*i)+yoffset)+bMargins), width-(2*bMargins), height-(2*bMargins), 8, TFT_CYAN);
        }
    }
}

无法编译,找不到问题????

感谢向我解释如何尝试解决问题的人。

亲切的问候

【问题讨论】:

  • 我建议你打破你已经采用的这种下划线开头的习惯。您不能有以下划线开头的文件范围变量。 (例如int _widthHere's why
  • 我还建议您将 #define XELEMENTS 13 替换为匿名 const 变量。 namespace { const short XELEMENTS = 13; } 因为thisthis
  • 也有这些!我会根据您的建议调整代码。

标签: c++ pointers visual-studio-code esp32 undefined-reference


【解决方案1】:

你对drawKeys的定义有两点错误:

  1. 你得到的是&amp; 而不是*
  2. 您忘记使用Keyboard:: 限定定义

在 Keyboard.cpp 文件中,

void drawKeys(MCUFRIEND_kbv &_tft)

应该改成说

void Keyboard::drawKeys(MCUFRIEND_kbv* _tft)

【讨论】:

  • 好的,我已经理解 */& 开关了。我是指针新手,弄错了,我的错。但是 Keyboard:: 前缀给了我“成员 'drawKeys' [-fpermissive] 上的额外限定 'Keyboard::'”并且未定义引用的错误仍然存​​在:(
  • 在 Keyboard.hi 中得到:void drawKeys(MCUFRIEND_kbv* myTft); 在 Keyboard.cpp 中:void drawKeys(MCUFRIEND_kbv* myTft) 我将函数称为 myTft-&gt;functionToRun(); 在 main.cpp 中:kb.drawKeys(&amp;tft); 我做得对吗?
  • 我认为您在遵循我的建议时可能错误地尝试更改标题。那是不对的。更改仅针对 .cpp 文件。 Keyboard.h 文件应为void drawKeys(MCUFRIEND_kbv* _tft);,keyboard.cpp 文件应为void Keyboard::drawKeys(MCUFRIEND_kbv* _tft)。请注意:declaration 在头文件中,definition 在 cpp 文件中。我说你必须限定 definition,而 declaration 已经在将它与类相关联的大括号内,因此它不需要进一步获得Keyboard::的资格。
  • 成功了!真是一个菜鸟的错误?非常感谢您的所有帮助和推荐!
【解决方案2】:

标题:

void drawKeys(MCUFRIEND_kbv* _tft);

CPP:

void drawKeys(MCUFRIEND_kbv &_tft)

那些不是等价的。决定一个签名并使用它。

【讨论】:

  • 知道了!谢谢。但是未定义引用的错误使我无法编译:(
猜你喜欢
  • 1970-01-01
  • 2020-06-26
  • 1970-01-01
  • 1970-01-01
  • 2021-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多