无法使派生的 WebDuino 类工作 - 使用 'Web_HelloWorld.ino' 编译错误

Can't get derived WebDuino class to work - compile errors with 'Web_HelloWorld.ino'

本文关键字:Web HelloWorld 错误 编译 ino 使用 派生 WebDuino 工作      更新时间:2023-10-16

我创建了一个名为WebServer_My2.h的工人类的派生类WebServer_My2KNJ.h(有关这些文件的详细信息,请参阅下面的注释部分),当我尝试编译示例程序时,我遇到了以下错误: Web_HelloWorld.ino

编译错误消息:(或查看附件"错误Msg.txt"):

Web_HelloWorld.ino:在函数'void setup()'中:Web_HelloWorld:57: 错误:从"void (*)(WebServer_My2KNJ&, WebServer_My2::ConnectionType, char*, bool)"到"void (*)(WebServer_My2&, WebServer_My2::ConnectionType, char*, bool)"的转换无效Web_HelloWorld:57:错误:初始化 'void WebServer_My2::setDefaultCommand(void (*)(WebServer_My2&, WebServer_My2::ConnectionType, char*, bool))' 的参数 1Web_HelloWorld:61: 错误:从"void (*)(WebServer_My2KNJ&, WebServer_My2::ConnectionType, char*, bool)"到 void (*)(WebServer_My2&, WebServer_My2::ConnectionType, char*, bool)"的转换无效Web_HelloWorld:61:错误:初始化"void WebServer_My2::addCommand(const char*, void (*)(WebServer_My2&, WebServer_My2::ConnectionType, char*, bool))"的参数 2

文件Web_HelloWorld.ino中的行webserver.setDefaultCommand(&helloCmd);在此时突出显示。

我的派生类:

/*
  WebServer_My2KNJ.cpp - Extension of the library class 'WebServer_My2'
  Created by: COG008
  Date Created: 2013/10/17
*/
#ifndef WebServer_My2KNJ_h
#define WebServer_My2KNJ_h
#include <..Webduino_My2WebServer_My2.h>
class WebServer_My2KNJ: public WebServer_My2
{
public:
// constructor for webserver object
WebServer_My2KNJ(const char *p_urlPrefix = "", int p_port = 80); 
};
WebServer_My2KNJ::WebServer_My2KNJ(const char *p_urlPrefix, int p_port) : 
WebServer_My2::WebServer_My2(p_urlPrefix, p_port)
{
;
}
#endif

注意:

  1. 我是C++新手,所以请耐心等待。
  2. 除"WebServer_My2KNJ.h"之外使用的所有文件基本上与"https://github.com/sirleech/Webduino"相同。
  3. 如果我使用"WebServer_My2.h"而不是"WebServer_My2KNJ.h",则"Web_HelloWorld.ino"编译并运行良好。
  4. 在父类"WebServer_My2.h"中,我所做的只是通过将"private:"更改为"protected:"以及类名来修改"WebServer.h"。
  5. 我要麻烦的原因是我想稍后向此类添加更多功能。 因此,为了使事情更干净,更简单,最好将我的代码放在派生类中。

简短回答:

helloCmd()更改为采用WebServer_My2&而不是WebServer_My2KNJ&

长答案:

看起来问题源于WebServer_My2.h文件中的Command函数指针类型def。它大概声明如下(第 ~169 行):

typedef void Command(WebServer_My2 &server, ConnectionType type,
                     char *url_tail, bool tail_complete);

这意味着它是一个指向函数的指针,该函数接受对WebServer_My2对象的引用作为其第一个参数(后跟其他一些参数)。有一些方法,例如 setDefaultCommand() ,可以接受这种确切类型的函数指针。C++在这里很严格。不能替换接受派生类型的引用参数的另一个函数指针。

我知道你说你没有修改helloCmd,但根据错误消息,我不得不假设你实际上将参数列表更改为:

void helloCmd(WebServer_My2KNJ &server, WebServer_My2::ConnectionType type, char *, bool)

因此,当代码尝试执行以下行时,问题就来了:

webserver.setDefaultCommand(&helloCmd);
webserver.addCommand("index.html", &helloCmd);

setDefaultCommand()addCommand() 方法需要一个函数指针,该指针将WebServer_My2引用作为其第一个参数。但是,helloCmd()实际上需要WebServer_My2KNJ参考。这是行不通的,因为类型不同(即使一个是从另一个派生的)。

一个快速的解决方案是按照我在上面的简短回答中建议的那样更改helloCmd()。这样,它至少应该能够编译和运行示例。如果要使用添加到子类中的扩展功能,则可以在函数中执行此操作:

WebServer_My2KNJ * myServer = dynamic_cast<WebServer_My2KNJ*>(&server);
if (myServer) {
    // myServer is safe to use here
}

然后,您可以使用myServer指针访问所有添加的 Web 服务器功能。请记住,它是一个指针,因此您需要使用 -> 运算符而不是 . 运算符来访问成员。

如果可能,dynamic_cast会向下转换继承层次结构。如果转换不起作用,它将返回一个空指针 (0),这就是需要if ()块的原因。