封装ESP8266 Web Server的Binder功能

Binder function for encapsulated ESP8266 Web Server

我正在尝试封装一个托管在 ESP8266 上的 WebServer,它也可以作为接入点。我正在使用活页夹来为服务器目标引用我封装的 class 中的方法,例如:如果客户端输入网站的根地址,它会运行以其中一种方法编写的响应代码封装的class。我在很多其他场合都使用过这个活页夹,但似乎我得到的错误指出了这个活页夹,我确信它是正确的。我是运行最新的Arduino ESP8266 SDK release 2.4.0-rc2,完整代码是here,相关要点如下:

活页夹变量的实例:

...
bind_member<WebServerAPClass, &WebServerAPClass::HandleRoot> handleRoot(this);
...
server->on("/", handleRoot);
...

活页夹:

template<class T, void(T::*PTR)()>
struct bind_member
{
    typedef void(*fn_type)();
    explicit bind_member(T* _ptr)
    {
        ptr = _ptr;
    }
    static void func(void)
    {
        (ptr->*PTR)();
    }
    operator fn_type()
    {
        return &func;
    }
private:
    static T*  ptr;
};
template<class T, void(T::*PTR)()>
T* bind_member<T, PTR>::ptr = NULL;

输出:

Setting wifi AP mode ... Setting soft-AP configuration ... [APConfig] local_ip: 192.168.88.1 gateway: 192.168.88.1 subnet: 255.255.255.0
[APConfig] DHCP IP start: 192.168.88.100
[APConfig] DHCP IP end: 192.168.88.200
Ready
Setting soft-AP ... [AP] softap config unchanged
Ready
AP IP address: 192.168.88.1
...[stack]...
ets Jan  8 2013,rst cause:2, boot mode:(3,6)

已解码的堆栈:

Exception 28: LoadProhibited: A load referenced a page mapped with an attribute that does not permit loads
Decoding 17 results
0x40206e65: std::function ::function(std::function  const&) at c:\users\rinaldi\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++.8.2/functional line 2380
0x40206e76: std::function ::function(std::function  const&) at c:\users\rinaldi\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++.8.2/functional line 2439
0x4020403e: ESP8266WebServer::on(String const&, HTTPMethod, std::function ) at C:\Users\Rinaldi\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266.4.0-rc2\libraries\ESP8266WebServer\src/ESP8266WebServer.cpp line 214
0x40206a70: operator new(unsigned int) at C:\Users\Rinaldi\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266.4.0-rc2\cores\esp8266/abi.cpp line 84
0x40201ff0: std::_Function_base::_Base_manager   >::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) at c:\users\rinaldi\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++.8.2/functional line 1931
0x402021cc: bind_member ::func() at C:\Users\Rinaldi\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266.4.0-rc2\libraries\RTCTimer/SimpleBinders.h line 14
:  (inlined by) std::_Function_handler   >::_M_invoke(std::_Any_data const&) at c:\users\rinaldi\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++.8.2/functional line 2071
0x40206e76: std::function ::function(std::function  const&) at C:\Users\Rinaldi\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266.4.0-rc2\libraries\ESP8266WebServer\src/ESP8266WebServer.cpp line 214
0x40204085: ~function at C:\Users\Rinaldi\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266.4.0-rc2\libraries\ESP8266WebServer\src/ESP8266WebServer.cpp line 214
:  (inlined by) ESP8266WebServer::on(String const&, std::function ) at C:\Users\Rinaldi\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266.4.0-rc2\libraries\ESP8266WebServer\src/ESP8266WebServer.cpp line 233
0x40201ff0: std::_Function_base::_Base_manager   >::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) at c:\users\rinaldi\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++.8.2/functional line 1931
0x402021cc: bind_member ::func() at C:\Users\Rinaldi\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266.4.0-rc2\libraries\RTCTimer/SimpleBinders.h line 14
:  (inlined by) std::_Function_handler   >::_M_invoke(std::_Any_data const&) at c:\users\rinaldi\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++.8.2/functional line 2071
0x4020215f: ~_Function_base at c:\users\rinaldi\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++.8.2/functional line 2029
:  (inlined by) ~function at c:\users\rinaldi\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++.8.2/functional line 2174
:  (inlined by) WebServerAPClass::Init() at C:\Users\Rinaldi\AppData\Local\Temp\arduino_build_415025\sketch/WebServerAP.cpp line 27
0x40201ff0: std::_Function_base::_Base_manager   >::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) at c:\users\rinaldi\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++.8.2/functional line 1931
0x402021cc: bind_member ::func() at C:\Users\Rinaldi\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266.4.0-rc2\libraries\RTCTimer/SimpleBinders.h line 14
:  (inlined by) std::_Function_handler   >::_M_invoke(std::_Any_data const&) at c:\users\rinaldi\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++.8.2/functional line 2071
0x40205c00: HardwareSerial::flush() at C:\Users\Rinaldi\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266.4.0-rc2\cores\esp8266/HardwareSerial.cpp line 180
0x40201f91: setup at C:\Users\Rinaldi\Documents\Arduino\MindTheGate/MindTheGate.ino line 11
0x40206ba3: loop_wrapper at C:\Users\Rinaldi\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266.4.0-rc2\cores\esp8266/core_esp8266_main.cpp line 57
0x40100a20: cont_norm at C:\Users\Rinaldi\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266.4.0-rc2\cores\esp8266/cont.S line 109

问题不在于活页夹,我忘记实例化 ESP8266WebServer。请参阅 github 上的项目以了解完整示例。