封装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 上的项目以了解完整示例。
我正在尝试封装一个托管在 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 上的项目以了解完整示例。