我之前问过类似的问题,但我意识到我无法对宏观和模板性做出正面或反面。我是一名 C(而不是 C++)程序员。
F() 实际上做了什么?什么时候将字符填充到 pgmem(闪存)中?它什么时候从 pgmem 中提取字符?它会缓存它们吗?它如何处理内存不足的情况?
我之前问过类似的问题,但我意识到我无法对宏观和模板性做出正面或反面。我是一名 C(而不是 C++)程序员。
F() 实际上做了什么?什么时候将字符填充到 pgmem(闪存)中?它什么时候从 pgmem 中提取字符?它会缓存它们吗?它如何处理内存不足的情况?
没有涉及模板,只有函数重载。宏做了F()
两件事:
用于PSTR
确保将文字字符串存储在闪存中(代码空间而不是数据空间)。但是,PSTR("some string")
不能打印,因为它会收到一个简单char *
的表示存储在闪存中的字符串的基地址。取消引用该指针将从数据中的同一地址访问一些随机字符。这也是为什么F()
...
将结果转换PSTR()
为__FlashStringHelper*
。print
和之类的函数println
被重载,以便在接收到__FlashStringHelper*
参数时,它们正确地取消引用闪存中的字符。
顺便提一句。对于 ESP32 库,这两个函数都在以下文件中定义:
# PSTR : ../Arduino/hardware/espressif/esp32/cores/esp32/pgmspace.h
# F : ../Arduino/hardware/espressif/esp32/cores/esp32/WString.h
F(x):
// An abstract class used as a means to provide a unique pointer type
// but really has no body
class __FlashStringHelper;
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
...
同样对于 ESP32,PSTR(x)
不需要,只是x : #define PSTR(s) (s)
。