在 C++ 中从 C 库正确初始化 typedef 结构
Initializing typedef struct from C library properly in C++
我想在我的 C++ 项目中包含一个库(控制 Raspberry Pi 上的 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++ 标准中编译。参见:Why does C++11 not support designated initializer list as 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};
当我实际 "render" 到 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];
几乎可以肯定是内存损坏的原因,因为只有缓冲区溢出或取消引用无效(但非 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}
。这不是什么大问题,但它允许您初始化数组中的多个条目。
我想在我的 C++ 项目中包含一个库(控制 Raspberry Pi 上的 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++ 标准中编译。参见:Why does C++11 not support designated initializer list as 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};
当我实际 "render" 到 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];
几乎可以肯定是内存损坏的原因,因为只有缓冲区溢出或取消引用无效(但非 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}
。这不是什么大问题,但它允许您初始化数组中的多个条目。