我有一个结构:
typedef struct Image {
byte height;
byte width;
byte data[];
} Image;
我创建了 2 个图像:
static const __flash Image GRID = {
.width = 16,
.height = 8,
.data = {
0x10, 0x10, 0x28, 0x28, 0x44, 0x44, 0x82, 0x82, ...
}
};
static const __flash Image HOUSE1 = {
.width = 24,
.height = 24,
.data = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ...
}
};
然后我创建一个指向图像的指针数组:
static const __flash Image *IMAGES[] = {
&GRID,
&HOUSE1,
};
我可以使用我的draw_image()
函数绘制图像:
void main(void)
{
draw_image(IMAGES[0], 16, 16);
}
我有一张地图:
typedef struct Map {
word cols;
word rows;
byte tiles[];
} Map;
static const __flash Map level_1 = {
.cols = 16,
.rows = 8,
.tiles = {
0,0,1,0,...
该.tiles
字段是IMAGES
数组中的索引列表。我这样做是因为我的引擎不知道有哪些可用的图像而不被告知:
void draw_map(const Map __memx *map, const Image __memx *tileset[]);
{
...
draw_image(tileset[map->tiles[index]], x, y);
...
}
如此称呼:
void main(void)
{
draw_map(&level_1, &IMAGES[0]);
}
编译器不喜欢这样,并给我不兼容的指针类型警告。地图未绘制:
note: expected
‘const __memx Image ** {aka const __memx struct Image **}’
but argument is of type
‘const __flash Image ** {aka const __flash struct Image **}’
我确实尝试[]
从draw_map()
声明中删除:
void draw_map(const Map __memx *map, const __memx Image *tileset);
但这给了我调用调用的错误draw_image()
:
error: incompatible type for argument 1 of ‘draw_image’
draw_image(tileset[0], c*8+(64 - r*8), r*8);
^
tile-engine.c:63:6: note: expected
‘const __memx Image * {aka const __memx struct Image *}’ but argument is of type
‘Image {aka const __memx struct Image}’
我哪里错了?
void draw_image(const Image __memx *image, int x, int y)
{
byte rows = image->height>>3;
byte cols = image->width>>3;
for(byte r=0 ; r<rows ; r++)
{
for(byte c=0 ; c<cols ; c++)
{
draw_tile(&image->data[(r*cols+c)*8], &image->data[(r*cols+c)*8], x+(c*8), y+(r*8));
}
}
}
问题似乎正是编译器所确定的:您将__flash
指针传递给需要指针的函数__memx
。
如果将 draw_map 的签名更改为
void draw_map(const Map __memx *map, const Image __flash *tileset[])
然后它工作正常。
好的,那么为什么这是必要的,当编译器可以接受__flash
第一个参数的指针时,它也被定义为__memx
?
原因是第一个指针是按值传递的,而第二个是按引用传递的(tileset
是一个指向指针的__memx
指针)。
根据 AVR 文档,__flash
指针是指向(显然)闪存的 16 位指针,而__memx
指针是 24 位指针,可以指向闪存或静态 RAM 中的位置。
看起来编译器足够聪明,可以在按值传递时将16 位__flash
指针提升为 24 位__memx
指针(类似于如何将 16 位 short 提升为 32 位 int 或 long),但它不能导致存储在内存中(在您的IMAGES
数组中)的 16 位指针扩展到 24 位。
由于__memx
指针的使用速度比__flash
指针慢(显然编译器必须检查实际指针是指闪存还是静态 RAM 并为每个指针使用不同的指令),如果您知道您的图像和地图数据将始终在闪存中,只需传递__flash
指针.
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句