Arduino C++将HTTP客户端初始化移至函数
我正在研究ESP-01(ESP8266板)项目,并提出一些HTTP请求。我正在尝试重构代码以保持干燥,但是我坚持如何将HTTP客户端初始化提取到功能上。
这是我工作的PUT请求函数:
void httpPut(const char* url, const char* data) {
WiFiClient client;
HTTPClient http;
http.begin(client, url);
http.addHeader("Content-Type", "application/json");
http.PUT(data);
http.end();
}
我的想法是制作这样的函数:
HTTPClient prepareRequest(const char* url) {
WiFiClient client;
HTTPClient http;
http.begin(client, url);
http.addHeader("Content-Type", "application/json");
return http;
}
并在我的所有请求函数中使用它:
void httpGet(const char* url) {
HTTPClient http = prepareRequest(url);
http.GET();
http.end();
}
我遇到了此编译器错误,但我不确定它的含义(提到的第90行是返回http;
):
/home/<user>/Code/Micro/mittari-micro/src/mittari.ino: In function 'HTTPClient prepareRequest(const char*)':
/home/<user>/Code/Micro/mittari-micro/src/mittari.ino:90:10: error: use of deleted function 'HTTPClient::HTTPClient(const HTTPClient&)'
90 | return http;
| ^~~~
In file included from /home/<user>/Code/Micro/mittari-micro/src/mittari.ino:2:
/home/<user>/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h:151:7: note: 'HTTPClient::HTTPClient(const HTTPClient&)' is implicitly deleted because the default definition would be ill-formed:
151 | class HTTPClient
| ^~~~~~~~~~
/home/<user>/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h:151:7: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = StreamString; _Dp = std::default_delete<StreamString>]'
In file included from /home/<user>/.platformio/packages/toolchain-xtensa/xtensa-lx106-elf/include/c++/10.3.0/memory:83,
from /home/<user>/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h:28,
from /home/<user>/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h:28,
from /home/<user>/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h:34,
from /home/<user>/Code/Micro/mittari-micro/src/mittari.ino:1:
/home/<user>/.platformio/packages/toolchain-xtensa/xtensa-lx106-elf/include/c++/10.3.0/bits/unique_ptr.h:468:7: note: declared here
468 | unique_ptr(const unique_ptr&) = delete;
| ^~~~~~~~~~
是否可以将共同功能提取到功能?我该怎么做?
I'm working on an ESP-01 (ESP8266 board) project and making some HTTP requests. I'm trying to refactor my code to keep it DRY, but I'm stuck on how to extract the http client initialization to a function.
Here is my working PUT request function:
void httpPut(const char* url, const char* data) {
WiFiClient client;
HTTPClient http;
http.begin(client, url);
http.addHeader("Content-Type", "application/json");
http.PUT(data);
http.end();
}
My idea was to make a function like this:
HTTPClient prepareRequest(const char* url) {
WiFiClient client;
HTTPClient http;
http.begin(client, url);
http.addHeader("Content-Type", "application/json");
return http;
}
And use it in all my request functions like this:
void httpGet(const char* url) {
HTTPClient http = prepareRequest(url);
http.GET();
http.end();
}
I get this compiler error, but I'm not really sure what it means (row 90 mentioned is return http;
):
/home/<user>/Code/Micro/mittari-micro/src/mittari.ino: In function 'HTTPClient prepareRequest(const char*)':
/home/<user>/Code/Micro/mittari-micro/src/mittari.ino:90:10: error: use of deleted function 'HTTPClient::HTTPClient(const HTTPClient&)'
90 | return http;
| ^~~~
In file included from /home/<user>/Code/Micro/mittari-micro/src/mittari.ino:2:
/home/<user>/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h:151:7: note: 'HTTPClient::HTTPClient(const HTTPClient&)' is implicitly deleted because the default definition would be ill-formed:
151 | class HTTPClient
| ^~~~~~~~~~
/home/<user>/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h:151:7: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = StreamString; _Dp = std::default_delete<StreamString>]'
In file included from /home/<user>/.platformio/packages/toolchain-xtensa/xtensa-lx106-elf/include/c++/10.3.0/memory:83,
from /home/<user>/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h:28,
from /home/<user>/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h:28,
from /home/<user>/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h:34,
from /home/<user>/Code/Micro/mittari-micro/src/mittari.ino:1:
/home/<user>/.platformio/packages/toolchain-xtensa/xtensa-lx106-elf/include/c++/10.3.0/bits/unique_ptr.h:468:7: note: declared here
468 | unique_ptr(const unique_ptr&) = delete;
| ^~~~~~~~~~
Is it possible to extract the common functionality to a function and how could I do that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在尝试在PrepareRequest函数结束时通过Value 返回httpclient对象(HTTP)。这意味着在这种情况下复制构造,并且编译器告诉您,该课程故意禁用复制构造。 (可能有很多原因。)
在Arduino环境中进行此操作的习惯是将您的“ WificLient客户端”和“ HTTPCLCLIENT HTTP”移至全局范围。然后将您的初始化代码写入“设置”函数,最后您可以在喜欢的任何功能中使用它们。这样,您可以将URL和标头的设置分离为“ PrepareRequest”功能,实际上HTTP进入了“ HTTPGET”功能,而无需它们返回任何内容。
有更复杂的解决方案,带有const参考,指针等……但是,除非您特别想走那条路,否则我会选择上面提到的解决方案。
You are trying to return a HTTPClient object (http) by value at the end of your prepareRequest function. This would mean copy construction in this case and the compiler is telling you that copy construction is deliberately disabled for this class. (There can be quite a number of reasons for this.)
How it is customary to do this in an Arduino environment is to move your "WiFiClient client" and "HTTPClient http" to global scope. Then write your initialization code into the "setup" function and finally you can use them in whatever functions you like. That way you can separate the setting of the URL and header into the "prepareRequest" function the actual http get into the "httpGet" function without them returning anything.
There are more complicated solutions with const references, pointers, etc... But unless you specifically want to go down that road, I would go for the solution mentioned above.
我将有效的和httpclient放在全球范围内,然后将准备方法更改为这样的空隙:
到目前为止,它似乎很好。
I put the WiFiClient and HTTPClient in global scope and changed the preparation method to void like this:
It seems to work fine so far.