2013-05-28 3 views
0

(btw Мне не разрешено malloc в этом, я пишу в c для c99) Я пытаюсь создать структуру-оболочку в c для массивов, чтобы держать вещи в порядке, поэтому Мне не нужно, чтобы сохранить прохождение указателя массива и длину вокруг, и может просто использовать:-структуруc array wrapper struct no malloc allowed

#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

Компиляторы принимают переключатель, определяющий макрос. Проверьте документацию для своего компилятора, которая разрешила бы это (например, '/ D' для MSVC). – hmjd

+0

Как именно это _more_ аккуратно, чем просто прохождение простого указателя и переменной простого размера? Чего вы пытаетесь достичь? – Lundin

ответ

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; 

Это может быть немного лучше кода, который у вас уже есть. Однако, на мой взгляд, это не стоит усилий, потому что любой нетривиальный макрос уменьшает читаемость кода.

1

Если вы создаете такую ​​структуру, а затем передаете ее по значению функции, тогда весь массив передается по значению. You do не хочу это.

На самом деле вам не нужен массив внутри структуры, просто объявите его в другом месте.

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); 
} 
+0

Имейте в виду, что этот код, вероятно, мало хорош в реальном мире, вне сферы действия этого вопроса. Вопрос заключается в попытке найти решение, без проблем. – Lundin

+0

Спасибо за ваши ответы.Я не уверен, поняли ли вы то, что я пытаюсь сделать, может быть, я не дал понять ... Я могу сделать byteArray_t * pbytes и передать это правильно? Мне просто кажется, что один аргумент делает api проще ... Главное, однако, было возможность определить объекты tlv_t как-то – Matthew

+0

@Matthew И это именно то, что делает этот код. Вы получаете один параметр функции вместо двух. В целом, я считаю, что из-за этого программа становится намного менее удобочитаемой. – Lundin