我正在使用一个灵活的数组成员来定义一个 USB 字符串描述符:
// defined
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bString[];
} ATTR_PACKED USB_StringDescriptor;
// declared
#define STR_PRODUCT L"My Cool Product"
const USB_StringDescriptor __flash manufacturer_string = {
sizeof(STR_PRODUCT)+2,
USB_DTYPE_String, // 0x03
STR_PRODUCT
};
这非常有效,并允许在别处定义实际的字符串常量,以便在项目之间轻松更改。但是由于编译器的限制,我不能再使用灵活的数组成员。我想避免对 char 数组进行硬编码,我基本上只需要将两个字节添加到宽字符数组的前面。是否有任何聪明的方法来声明可以实现此目的的数组或预处理器宏?
最佳答案
如果不以可移植的方式使用动态内存分配,我认为无法实现具有灵活大小的结构。
但是,以下两种具有固定大小结构的方法之一也可能适用于您:
- 定义结构使得
bstring
是一个固定大小的数组;如果您的程序中只有一个STR_PRODUCT
,您可以使用它的大小。如果您有更多结构实例,请使用您希望允许的最大大小定义数组。 - 用
bstring
定义一个指针结构;您仍然可以使用指向字符串文字的指针对其进行初始化。请注意,一个对象将不会包含连续内存块中的所有信息。如果您需要包含所有信息的连续内存,则此方法 2 将不起作用。
请参阅以下演示这两种方法的程序:
#define STR_PRODUCT_1 L"My Cool Product"
#define STR_PRODUCT_2 L"Another Cool Product"
#define MAX_PRODUCT_STR "012345678901234567890"
// Approach 1:
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
wchar_t bString[sizeof(MAX_PRODUCT_STR)];
} USB_StringDescriptor;
const USB_StringDescriptor manufacturer_string = {
sizeof(STR_PRODUCT_1)+2,
0x03,
STR_PRODUCT_1
};
const USB_StringDescriptor manufacturer_string2 = {
sizeof(STR_PRODUCT_2)+2,
0x03,
STR_PRODUCT_2
};
// Approach 2:
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
wchar_t *bString;
} USB_StringDescriptor_V2;
const USB_StringDescriptor_V2 manufacturer_string_v2 = {
sizeof(STR_PRODUCT_1)+2,
0x03,
STR_PRODUCT_1
};
const USB_StringDescriptor_V2 manufacturer_string_v2_2 = {
sizeof(STR_PRODUCT_2)+2,
0x03,
STR_PRODUCT_2
};
int main() {
wprintf(L"1: %ls\n",manufacturer_string.bString);
wprintf(L"2: %ls\n",manufacturer_string2.bString);
wprintf(L"1 ptr: %ls\n",manufacturer_string_v2.bString);
wprintf(L"2 ptr: %ls\n",manufacturer_string_v2_2.bString);
}
关于c - 替代灵活数组成员,无需动态内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45575808/