c - 替代灵活数组成员,无需动态内存分配

标签 c arrays flexible-array-member

我正在使用一个灵活的数组成员来定义一个 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 数组进行硬编码,我基本上只需要将两个字节添加到宽字符数组的前面。是否有任何聪明的方法来声明可以实现此目的的数组或预处理器宏?

最佳答案

如果不以可移植的方式使用动态内存分配,我认为无法实现具有灵活大小的结构。

但是,以下两种具有固定大小结构的方法之一也可能适用于您:

  1. 定义结构使得bstring 是一个固定大小的数组;如果您的程序中只有一个 STR_PRODUCT,您可以使用它的大小。如果您有更多结构实例,请使用您希望允许的最大大小定义数组。
  2. 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/

相关文章:

c++ - R代码或.R文件的DLL

c - 在C程序中使用cp命令获取要复制的文件列表

arrays - 如何像我们在 C 中创建的那样在 golang 中创建一个结构数组

java - 在特定位置将数组重新排序为 arrayList

c++ - 使用模板和基类实现灵活的数组成员

c - C 中任意碱基到任意碱基的碱基转换(最多 36 个)

c - 如何使用 mingw 在 Windows 中构建 protobuf-c?

c - 使用指针在函数内部定义数组

c - 在 mmap 中使用灵活的数组成员

c++ - 具有灵活阵列成员的打包结构的可移植替代方案