Arduino:将函数传递给类,返回字符串

Arduino: pass function to class, returning String

本文关键字:返回 字符串 函数 Arduino      更新时间:2023-10-16

我正在尝试让我的Arduino类返回带有各种日志记录信息的字符串消息。通过大量的试验和错误,我设法将对日志记录函数的引用传递给类,但只能获得 char* 而不是字符串,我希望能够发送字符串,从而更容易发回各种数据。

我已经有了第一部分。 草图:

#include <Test.h>
#include <string.h>
void setup() {
Serial.begin(115200);
Test t;
t.setLogging(writeLog);
writeLog("Test message!" + String(" .... "));
t.doSomething("This is useful.");
t.doSomething("This as well.n");
t.doSomething("This is even more useful.n");
bool b = true;
}
void loop() {
}
void writeLog (char* message) {
Serial.print("char function: ");
Serial.print(message);
}
void writeLog (String message) {
Serial.print("String function: ");
Serial.println(message);
}

头文件:

#ifndef TEST_h
#define TEST_h
class Test
{
public:
Test();       // The constructor.
void setLogging(void (*)(char*)); // Takes function setting where to log.
void doSomething(char*);
};
#endif

班级:

#include <Test.h>
typedef void (*LogFunction)(char*);
LogFunction writeLog;
Test::Test () { 
}
void Test::doSomething (char* s) {
// Do something useful and log the result.
writeLog(s);
}
void Test::setLogging (void (*f)(char*) ) {
writeLog = f;
return;
}

现在我希望我的类能够做的是发送这样的信息,作为字符串,而不是 char*(我也没有找到一种简单的方法将"任何东西"转换为 char*,然后连接两个或多个字符串):

writeLog ("HydroMonitorECSensor::setCalibration  Receiving calibration - haveCalibration = " + String(haveCalibration));
writeLog ("HydroMonitorECSensor::setCalibration  calibratedSlope = " + String(calibratedSlope));
writeLog ("HydroMonitorECSensor::setPins  capPos set to " + String(capPos));

其中haveCalibration是一个bool(作为字符串变为"真"或"假"),calibratedSlope是一个doublecapPos是一个int。这样,我可以轻松干净地将完整的行发送到记录器。在主脚本中工作得很好 - 而不是来自类。

我尝试简单地将char*更改为String并将#include <string.h>添加到库文件中,但它不起作用。

在测试中.cpp我得到void Test::setLogging (void (*f)(String) ) {,在Test.h中void setLogging(void (*)(String));,现在我收到错误消息:

In file included from /home/wouter/Arduino/libraries/Test/Test.cpp:1:0:
/home/wouter/Arduino/libraries/Test/Test.h:10:29: error: expected ',' or '...' before '(' token
void setLogging(void (*)(String)); // Takes function setting where to log.
^
/home/wouter/Arduino/libraries/Test/Test.cpp:16:40: error: variable or field 'setLogging' declared void
void Test::setLogging (void (*f)(String) ) {
^
/home/wouter/Arduino/libraries/Test/Test.cpp:16:31: error: 'f' was not declared in this scope
void Test::setLogging (void (*f)(String) ) {
^
/home/wouter/Arduino/libraries/Test/Test.cpp:16:34: error: 'String' was not declared in this scope
void Test::setLogging (void (*f)(String) ) {
^
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

建议?

其他信息,可能很重要:我正在使用Arduino IDE并针对ESP8266进行编译。

您正在使用 Arduino 提供的String类,但没有在test.h头文件中包含Arduino.h标头。这会导致它找不到String类并且编译失败。

以下作品:

main.cpp

#include <Arduino.h>
#include <test.hpp>
void writeLog (char* message);
void writeLog (String message);
void setup() {
Serial.begin(115200);
Test t;
t.setLogging(writeLog);
writeLog("Test message!" + String(" .... "));
t.doSomething("This is useful.");
t.doSomething("This as well.n");
t.doSomething("This is even more useful.n");
bool b = true;
}
void loop() {
}
void writeLog (char* message) {
Serial.print("char function: ");
Serial.print(message);
}
void writeLog (String message) {
Serial.print("String function: ");
Serial.println(message);
}

test.hpp

#ifndef TEST_h
#define TEST_h
#include <Arduino.h> //for "String" class
//Typdef for the log function. Takes a String, returns nothing
typedef void (*LogFunction)(String);
class Test
{
public:
Test();       // The constructor.
//  void setLogging(void (*)(char*)); // Takes function setting where to log.
void setLogging(LogFunction); //use the typedef here
void doSomething(char*);
};
#endif

test.cpp

#include <test.hpp>

LogFunction writeLog;
Test::Test () {
}
void Test::doSomething (char* s) {
// Do something useful and log the result.
writeLog(s);
}
//void Test::setLogging (void (*f)(char*) ) {
void Test::setLogging (LogFunction f) { //also use typedef here
writeLog = f;
return;
}

在可能出现的其他事情中,编译器会告诉您它无法解析标识符String。 这可能有几个原因:首先,你写String,而不是string(注意你写作中的大写字母)。其次,如果您编写string而不是std::string,则无法解决,除非您声明了using namespace std(由于多种原因,这不是首选变体)或using std::string。第三,类std::string在标头<string>中声明,这与<string.h>不同。

所以我会写#include <string>然后使用std::string.