在C 中正确从C库中初始化Typedef struct

Initializing typedef struct from C library properly in C++

本文关键字:初始化 Typedef struct      更新时间:2023-10-16

我想在我的C 项目中包含一个库(控制RASPBERRY PI上的RGB LED条)。导入库的运行良好,但我有一个很大的问题,可以正确初始化某些结构。我很迷失在哪里可以找到适当的语法,我做了很多谷歌搜索,但没有走得很远。

首先,我想让库随附的示例应用程序进行。请参阅:https://github.com/richardghirst/rpi_ws281x/blob/master/mains/main.c

我的主要问题是这个。我该怎么做在C 方式下方做的事情?

ws2811_t ledstring =
{
    .freq = TARGET_FREQ,
    .dmanum = DMA,
    .channel =
    {
        [0] =
        {
            .gpionum = GPIO_PIN,
            .count = LED_COUNT,
            .invert = 0,
            .brightness = 255,
        },
        [1] =
        {
            .gpionum = 0,
            .count = 0,
            .invert = 0,
            .brightness = 0,
        },
    },
};

初始化的方式是特定的,并且在任何当前的C 标准中均不编译。请参阅:为什么C 11不支持指定的初始化器列表为C99?到目前为止,我只使用了自己的结构,也从未使用过Typedef,所以我只是混淆了这里定义结构的方式。

以这种方式定义了上面初始化的结构。请参阅:https://github.com/richardghirst/rpi_ws281x/blob/master/ws2811.h

typedef struct
{
    int gpionum;                          //< GPIO Pin with PWM alternate function
    int invert;                           //< Invert output signal
    int count;                            //< Number of LEDs, 0 if channel is unused
    int brightness;                       //< Brightness value between 0 and 255
    ws2811_led_t *leds;                   //< LED buffers, allocated by driver based on count
} ws2811_channel_t;
typedef struct
{
    struct ws2811_device *device;                //< Private data for driver use
    uint32_t freq;                               //< Required output frequency
    int dmanum;                                  //< DMA number _not_ already in use
    ws2811_channel_t channel[RPI_PWM_CHANNELS];
} ws2811_t;

我尝试的是:

ws2811_led_t matrix[WIDTH][HEIGHT];
ws2811_channel_t channel0 = {GPIO_PIN,LED_COUNT,0,255,*matrix};
ws2811_t ledstring = {nullptr,TARGET_FREQ,DMA,channel0};

当我真正"渲染"到LED带上时,它会汇编但会导致Malloc错误:

int x, y;
for (x = 0; x < WIDTH; x++)
{
    for (y = 0; y < HEIGHT; y++)
    {
        cout << "LEDs size: " << (y * WIDTH) + x << endl;
        ledstring.channel[0].leds[(y * WIDTH) + x] = matrix[x][y];
    }
}

在循环结构完成后导致此错误消息:

malloc(): memory corruption (fast): 0x021acaa8

您应该能够使用以下启动器使用:

ws2811_t ledstring =
{
    nullptr,
    TARGET_FREQ,
    DMA,
    {
        { GPIO_PIN, 0, LED_COUNT, 255 },
        { 0 }
    }
};

此行

ledstring.channel[0].leds[(y * WIDTH) + x] = matrix[x][y];

几乎可以肯定是记忆损坏的原因,因为这只能通过缓冲区超支或提出无效(但非无效)指针发生。

我在此代码中看到了一些问题

ws2811_channel_t channel0 = {GPIO_PIN,LED_COUNT,0,255,*matrix};
ws2811_t ledstring = {nullptr,TARGET_FREQ,DMA,channel0};

首先,在channel0的初始化器中,您将leds字段设置为matrix[0][0]的内容而不是其地址。您需要将最终初始化器更改为matrix

接下来,您将初始化channel0.leds指向两个维数组matrix,但将其视为ledstring.channel[0].leds[(y * WIDTH) + x]中的单个维数组。这可能应该是ledstring.channel[0].leds[x][y]

最后,ledstring的最后一个初始化器可能是{channel0},为了清楚起见。这不是一个大问题,但它允许您在数组中初始化一个以上的条目。