我尝试从www.example.com API中提取天气图标openweathermap.org,并使用u8 g2库(Arduino IDE,C++11)在ESP 32驱动的OLED显示器上显示它们。
在openweathermap.org天气API中,16种天气类型被定义为const *char[]
,例如"01d"
、"01n"
、"02d"
等。
u8 g2库使用unsigned char数组来定义XBM位图格式的图标。我定义了所有的图标,如下所示:
static unsigned char icon01d[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
...
}
图标可以通过以下方式显示在OLED上:
u8g2.drawXBMP( 96, 0, 32, 32, icon01d );
我想使用一个std::map将字符串从天气API链接到指向图标的指针,如:
map< string, unsigned char[]* > WEATHER_ICONS = {
{ "01d", &icon01d },
{ "01n", &icon01n },
...
};
然后(在我的幻想中)能够显示适当的图标,如:
u8g2.drawXBMP( 96, 0, 32, 32, *WEATHER_ICONS[ weatherIcon ] );
weatherIcon是强制转换为字符串的const *char[]
。
我尝试了各种方法来设置Map:
std::map< std::string, <<variable reference>> > WEATHER_ICONS = {
{ "01d", &icon01d },
{ "01n", &icon01n }
};
根据表中的<<variable reference>>
,我得到各种错误消息:
| 引用的变量已使用|返回错误消息|
| - ------|- ------|
| unsigned char[128]*
|template argument 2 is invalid
|
| unsigned char[]*
|template argument 2 is invalid
|
| unsigned char*[128]
|x1米11米1x|
| unsigned char*[]
|could not convert '{{"01d", (& icon01d)}, {"01n", (& icon01n)}}' from '<brace-enclosed initializer list>' to 'std::map<std::__cxx11::basic_string<char>, unsigned char* []>'
|
| unsigned char**
|could not convert '{{"01d", (& icon01d)}, {"01n", (& icon01n)}}' from '<brace-enclosed initializer list>' to 'std::map<std::__cxx11::basic_string<char>, unsigned char**>'
|
没有一个错误信息对我很有帮助。看起来我已经到达了“c指针地狱”。
我看到了关于stackoverflow的建议,可以定义一个指向指针数组的指针,比如unsigned char**
,但是我缺少足够的细节来让它工作。
正确的解决方案是什么?
作为一种解决方案,我已将其实现为:
if ( strcmp( weatherIcon, "01d" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon01d );
else if( strcmp( weatherIcon, "01n" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon01n );
else if( strcmp( weatherIcon, "02d" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon02d );
else if( strcmp( weatherIcon, "02n" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon02n );
else if( strcmp( weatherIcon, "03d" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon03d );
else if( strcmp( weatherIcon, "03n" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon03n );
else if( strcmp( weatherIcon, "04d" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon04d );
else if( strcmp( weatherIcon, "04n" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon04n );
else if( strcmp( weatherIcon, "09d" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon09d );
else if( strcmp( weatherIcon, "09n" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon09n );
else if( strcmp( weatherIcon, "11d" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon11d );
else if( strcmp( weatherIcon, "11n" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon11n );
else if( strcmp( weatherIcon, "13d" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon13d );
else if( strcmp( weatherIcon, "13n" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon13n );
else if( strcmp( weatherIcon, "50d" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon50d );
else if( strcmp( weatherIcon, "50n" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon50n );
这很有效,但不是很优雅。
3条答案
按热度按时间busg9geu1#
在C和C++中,计算数组名会产生指向数组中第一个值的指针。
您的
static unsigned char icon01d[]
实际上是伪装的unsigned char *
。因此:从你的问题中还不清楚是否有必要知道每个这样的数组的大小,如果所有这些
unsigned char
数组大小相同,那么就可以了,否则,也许你可以存储两个数组,像下面这样:c9qzyr3d2#
在调用
drawXBMP
的第一个示例中,您有:那么,在这个例子中
icon01d
是什么?因为你传递的是一个没有索引的数组名,所以你实际上传递的是一个指向数组中第一个元素的指针。在这个例子中,它是一个unsigned char*
。当你声明你的map时,你应该使用它,像这样:
那么应该这样调用
drawXBMP
:toe950273#
看来解决办法是:
别问我怎么知道的。
感谢两位回答这个问题,如果问题不清楚,我很抱歉。