一个指针传递给指针数组到C结构

问题描述 投票:0回答:1

我有一个结构:

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));
        }
    }
}
c pointers struct
1个回答
2
投票

这个问题似乎是什么编译器已经确定:你传递一个__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指针由值传递给它时__memx指针24位(类似于它如何能够促进一个16位短至32位int或长),但它不能使一个储存在内存(在你的IMAGES阵列)一个16位的指针扩展到24位。

由于__memx指针比__flash指针慢用(显然,编译器检查,如果实际的指针指到闪存或静态RAM,并使用不同的指令对每个),如果你知道你的图像和地图数据将永远在闪,只是通过__flash指针。

© www.soinside.com 2019 - 2024. All rights reserved.