正确初始化从C库typedef结构在C ++(Initializing typedef struct

2019-10-23 00:08发布

我想在我的C ++项目库(控制RGB LED的树莓派条)。 导入库工作正常,但我有相当的问题,在正确初始化一些结构。 我几乎失去了哪里,甚至找到正确的语法,我做了很多谷歌上搜索,但没有得到很远。

我想首先是获得示例应用程序会随库。 请参阅: https://github.com/richardghirst/rpi_ws281x/blob/master/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 ++标准不编译。 请参阅: 为什么C ++ 11不支持指定的初始化列表为C99? 到目前为止,我只用我自己的结构,也从来没有使用过的typedef,所以我只是困惑结构在这里定义的方式。

该被上述初始化该结构(S)为以这种方式定义。 请参阅: 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};

这编译,但在一个malloc错误结果当我来到实际上是“渲染”的LED灯条:

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

Answer 1:

您应该能够使用使用以下初始化:

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


Answer 2:

这条线

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

几乎可以肯定是存储器损坏的原因,作为可以仅通过任意一方的缓冲区溢出或访问一个空的(但非NULL)指针发生。

我看到在这个代码中的一些问题

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}为清楚起见。 这不是一个大问题,但它允许您初始化数组中的多个条目。



文章来源: Initializing typedef struct from C library properly in C++
标签: c++ c struct