(顺便说一句,我不允许在这里使用malloc,我用c编写c99) 我正在尝试在c中为数组创建一个包装器结构以保持整洁,所以我不需要继续传递数组指针和长度,并且可以只使用结构:
#define MAX_LEN 64
typedef struct {
uint8_t data[MAX_LEN];
size_t len;
} byteArray_t;
如果已知MAX_LEN,那么这是好的,但是有一种方法可以使长度变量虽然在编译时已知,所以例如我可以有类似的东西:
typedef struct {
byteArray_t tag;
byteArray_t length;
byteArray_t value;
} tlv_t;
其中对应tag
的数组的大小为MAX_TAG_LEN
,其他等等 - 所以我需要以某种方式告诉编译器就是这种情况......
有人有任何想法吗?谢谢!
修改
好的,抱歉这个混乱。这就是我想要做的。 我目前基本上有以下结构:
// tag object
typedef struct {
uint8_t data[MAX_TAG_LENGTH_IN_BYTES];
uint32_t len;
} tlvTag_t;
// length object
typedef struct {
uint8_t data[MAX_LENGTH_OF_LENGTH_IN_BYTES];
uint32_t len;
} tlvLength_t;
typedef struct tlv tlv_t;
// value object definition
typedef struct {
// can consist of a byte array, or a list of sub TLVs
union {
uint8_t data[MAX_VALUE_LENGTH_IN_BYTES];
// data can be parsed into subTLVs
tlv_t* subTLVs;
};
// need to store the number of subTLVs
uint32_t numberOfSubTLVs;
// len is the total length of the data represented:
// the total length of the subTLVs placed end to end
// or the length of the data array.
uint32_t len;
} tlvValue_t;
// tlv object definition
struct tlv {
tlvTag_t tag;
tlvLength_t len;
tlvValue_t value;
// total length of entire tlv block (not value length)
// (if there are sub TLVs, place them end to end)
uint32_t totalLen;
};
我认为如果我可以将数组包装在另一个结构中以避免所有代码重复并且能够传递更少的参数,那么设计会更好,但我不能因为我不知道如何告诉编译器创建不同大小的字节数组 - 也许可以使用宏?希望这是有道理的。
答案 0 :(得分:1)
如果你创建一个像这样的结构,然后通过值将它传递给一个函数,那么整个数组将通过值传递。你做不想那样。
实际上你不需要在struct中使用数组,只需在别处声明它。
typedef struct {
uint8_t* data;
size_t len;
} byteArray_t;
int main()
{
uint8_t some_array[X];
...
byteArray_t wrapper = {some_array, X};
some_function (&wrapper);
}
答案 1 :(得分:1)
似乎你试图以某种方式声明一个内容依赖于参数的结构。在c ++中,这可以通过模板实现:
template <size_t MAX_LEN>
struct byteArray_t
{
uint8_t data[MAX_LEN];
size_t len;
};
...
byteArray_t<MAX_TAG_LENGTH_IN_BYTES> tag;
byteArray_t<MAX_LENGTH_OF_LENGTH_IN_BYTES> len;
...
这很简单。
要在C中完成相同的操作,您可以使用宏:
#define DECLARE_BYTE_ARRAY_T(your_type_name, MAX_LEN) \
typedef struct { \
uint8_t data[MAX_LEN]; \
size_t len; \
} your_type_name
DECLARE_BYTE_ARRAY_T(tlvTag_t, MAX_TAG_LENGTH_IN_BYTES);
DECLARE_BYTE_ARRAY_T(tlvLenght_t, MAX_LENGTH_OF_LENGTH_IN_BYTES);
...
tlvTag_t tag;
tlvLength_t len;
或(相同)没有声明类型(如果你不需要你的结构名称,那就很好):
#define BYTE_ARRAY_T(MAX_LEN) \
struct { \
uint8_t data[MAX_LEN]; \
size_t len; \
}
BYTE_ARRAY_T(MAX_TAG_LENGTH_IN_BYTES) tag;
BYTE_ARRAY_T(MAX_LENGTH_OF_LENGTH_IN_BYTES) len;
这可能比您已有的代码略胜一筹。但是,在我看来,这不值得付出努力,因为任何非平凡的宏都会降低代码的可读性。