繁体   English   中英

将指针传递给指向C结构的指针数组

[英]Pass a pointer to an array of pointers to a C struct

我有一个结构:

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[])

然后就可以了

好的,当编译器可以接受第一个参数(也定义为__memx__flash指针时,为什么这样做是必要的?

其原因是,而第二个是通过引用(通过第一指针由值传递tileset是一个指向__memx指针)。

根据AVR文档, __flash指针是16位指针为(明显)闪速存储器,而__memx指针是24位的指针可以指向任何闪光灯或在静态RAM位置。

看起来编译器很聪明,可以在按值传递值时将16位__flash指针提升为24位__memx指针(类似于如何将16位short提升为int或long的32位),但是它不能使存储在内存中( IMAGES数组中)的16位指针扩展为24位。

由于__memx指针的使用速度比__flash指针慢(显然,编译器必须检查实际指针是指向闪存还是静态RAM并针对每个指针使用不同的指令),因此如果您知道图像和映射数据始终位于闪存中,传递__flash指针。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM