2015-03-03 72 views
2

我想用字節數值和字符串一次初始化一個字節數組。基本上陣列是數據結構的序列化表示等用字節和字符串初始化C數組

struct foo { 
    uint8 param1; 
    uint8 stringLen; 
    const char * string; 
    uint8 param2; 
}; 

儘管API期望字節數組,我有超過沒有控制。 API期望數組被靜態初始化爲sizeof運算符來報告實際大小。我知道可以使用字符串文字或特定字節初始化一個數組,儘管任何初始化數組的嘗試都是以字符串文字作爲指針地址(這是什麼,這裏並不令人意外)。

我正在考慮定義我自己的struct並用它初始化數組,但我不相信結構或字符串文字是編譯時序列化的。我似乎無法想到這樣的語法,我甚至不確定這是否可能。任何輸入讚賞。

最後的手段可能是像array[] = "\x66oo"這樣的初始化數組,但這隻會比簡單的array[] = {0x66, 'o', 'o'}略微維護,兩種解決方案都需要外部(python?)生成器。

+2

您可以定義結構的初始化的'const'數組,它應該在編譯時初始化。但請注意結構填充,請參閱編譯器手冊,瞭解如何在沒有填充的情況下打包結構。 – 2015-03-03 11:16:35

+1

@JoachimPileborg這是一個好主意,但它不會序列化字符串文字,編譯器仍然可以自由地將它們存儲在任何地方。一個固定大小的字符數組將會這樣做(如果字符串字面大小是固定的)。 – Vagish 2015-03-03 11:32:30

+0

但是,IIUC,真正的問題是C字符串的標準初始化程序是否假定應該附加一個nul結束符? (字符串連接C字符串將允許'char array [] =「a」「\ x05」「Hello」「b」;',但生成的initalizer將是9個字節長而不是8個字節) – joop 2015-03-03 12:19:50

回答

2

您必須初始化使用這樣的功能的字節數組:

uint8 *initByteArray(const struct foo *foo) 
{ 
    unsigned slen = foo->string ? strlen(foo->string) : 0; 
    assert(slen <= 255); 
    uint8 *array = malloc(slen + 3); 
    unsigned i = 0; 
    array[i++] = foo->param1; 
    array[i++] = (uint8)slen; 
    if (slen) { 
     strncpy(&array[i], foo->string, slen); 
     i += slen; 
    } 
    array[i++] = foo->param2; 
    return array; 
} 

如果struct包含大於1(即uint16等)的長度任意整數,那麼你還需要考慮它們在編碼過程中的排列順序。

+0

我知道運行時方法來初始化一個數組,雖然API預計該數組是靜態的(BSS段)初始化'sizeof'來報告實際大小。對不起,誤解,編輯 – friendzis 2015-03-03 11:32:09

+0

@friendzis嗯,這聽起來不像一個簡單的問題解決的問題... – trojanfoe 2015-03-03 12:35:20

0

C允許將字符串文字(也在初始化程序中)分解;編譯器會爲你粘貼它們。

所以,你可以這樣做:

char unit1[8] = "\x40" "\x05" "Hello" "\x3e"; 
char unit2[9] = "\x40" "\x06" "World!" "\x3e"; 

char unitBoth[] = "\x40" "\x05" "Hello" "\x3e" 
        "\x40" "\x06" "World!" "\x3e"; 

unitBoth[]陣列沒有定義的大小;它只比單獨兩個數組的總和長一個字節(nul字節)。


#include <stdio.h> 
#include <string.h> 

int main(void) 
{ 
unsigned idx, len; 

printf("Unit1 Size = %zu\n", sizeof unit1); 
for (idx=0; idx < sizeof unit1; idx++) { 
     printf("%u : %02x\n" , idx , 0xff & unit1[idx]); 
     } 

printf("\nUnit2 Size = %zu\n", sizeof unit2); 
for (idx=0; idx < sizeof unit2; idx++) { 
     printf("%u : %02x\n" , idx , 0xff & unit2[idx]); 
     } 

printf("\nUnitBoth Size = %zu\n", sizeof unitBoth); 
for (idx=0; idx < sizeof unitBoth; idx++) { 
     printf("%u : %02x\n" , idx , 0xff & unitBoth[idx]); 
     } 

return 0; 
} 

當然,你可以創建一個程序或腳本生成的定義。 (並將它們包含在您的主程序中,可能位於全局範圍內)