簡體   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