2013-10-16 50 views
0

我正在讀取來自byteData的幾個字節,如下面在我的C++代碼中所述。 byteData中的實際值是BIG-ENDIAN字節順序格式的二進制BLOB字節數組。所以我不能只是簡單地「投」字節數組爲String ..如何在從C++中的bytearray中提取字節時交換64位整數?

byteData字節數組是由這三樣東西 -

First is `schemaId` which is of two bytes (short datatype in Java) 
Second is `lastModifiedDate` which is of eight bytes (long datatype in Java) 
Third is the length of actual `byteArray` within `byteData` which we need from `byteData`. 
Fourth is the actual value of that `byteArray` in `byteData`. 

現在我想提取從byteData上述特定信息在C++ ......不知怎的,我能提取schemaId和我得到的值也是正確的。現在我不知道如何從中提取其他的東西......

uint16_t schemaId; 
uint64_t lastModifiedDate; 
uint16_t attributeLength; // or it should be uint32_t? 
const char* actual_binary_value; 

while (result.next()) { 
    for (size_t i = 0; i < result.column_count(); ++i) { 
     cql::cql_byte_t* byteData = NULL; 
     cql::cql_int_t size = 0; 
     result.get_data(i, &byteData, size); 

     // I cannot just "cast" the byte array into a String 
     // value = reinterpret_cast<char*>(byteData); 

     // this works fine 
     schemaId = ntohs(*reinterpret_cast<uint16_t*>(byteData)); 

     // now how to retrieve lastModifiedDate, length of binary value and actual_binary_value from byteData? 
     // the below doesn't works.. 
      lastModifiedDate = be64toh(*reinterpret_cast<uint64_t*>(data)); 

     // And how to extract other things as well? 

    } 

    // this prints out `9223090561897746107` but it should print out `1289811105109` 
    cout<< lastModifiedDate <<endl; 

    // And print out other things.. 
} 

如果有人需要然後看到我的java代碼這是我的java代碼 -

byte[] avroBinaryValue = text.getBytes(); 

    long lastModifiedDate = 1289811105109L; 
    short schemaId = 32767; 

    int size = 2 + 8 + 4 + avroBinaryValue.length; // short is 2 bytes, long 8 and int 4 

    ByteBuffer bbuf = ByteBuffer.allocate(size); 
    bbuf.order(ByteOrder.BIG_ENDIAN); 

    bbuf.putShort(schemaId); 
    bbuf.putLong(lastModifiedDate); 
    bbuf.putInt(avroBinaryValue.length); 
    bbuf.put(avroBinaryValue); 

    // merge everything into one bytearray. 
    byte[] bytesToStore = bbuf.array(); 

    Hex.encodeHexString(bytesToStore) 

任何人可以幫助我什麼錯我在C++代碼正在做的,爲什麼我不能從中等領域適當提取lastModifiedDate呢?據我所知lastModifiedDate是64位整數,那麼有什麼辦法在這裏換出64位整數嗎?或者其他更好的方式來做轉換?

總之,我試圖提取schemaIdlastModifiedDateavroBinaryValue.length和用C是字節數組avroBinaryValue ++ ..

我能提取schemaId但我被困在其他的事情現在...

+0

可能重複【如何提取字節數組的各個字段(在大尾數)在C++] (http://stackoverflow.com/questions/19392004/how-to-extract-individual-fields-from-byte-array-which-is-in-big-endian-in-c) –

+0

@JonathanPotter:在這個問題我問的schemaId和其他東西我同意,但一些人建議我尋找如何交換64位整數從它提取lastModifiedDate,我做了一些研究,我無法弄清楚......所以這就是爲什麼張貼爲一個新的問題她e .. – AKIWEB

回答

1

你的方法看起來不錯,我看到的只有兩個可能的問題。如圖所示被簡單地鑄造未定義的變量data作爲uint64_t

  1. 您的代碼。確保您實際上正在通過數據緩衝區前進並轉換正確的數據。

  2. 平臺依賴。從我所看到的64位字節交換函數(be64toh,betoh64,ntohll等)在所有平臺上都沒有得到普遍支持。您可能需要在平臺上使用不同的功能,並且/或者如果您希望代碼獨立於平臺,可以自動檢測哪些功能可行。例如,參見類似的問題herehere

至於如何獲取數據,這樣的事情應該工作:

int index=0; 
schemaId = ntohs(*reinterpret_cast<uint16_t*>(&byteData[index])); 
index += 2; 
lastModifiedDate = be64toh(*reinterpret_cast<uint64_t*>(&byteData[index])); 
index += 8; 
attributeLength = ntohl(*reinterpret_cast<uint32_t*>(&byteData[index])); 
index += 4; 
actual_binary_data = (const char *)&byteData[index]; 
+0

感謝您的建議......在對應您的第一點,我做錯了什麼?我們不能手動交換位而不是使用某些預定義的函數? – AKIWEB

+0

用示例代碼更新了答案。 Re:手動交換,你應該避免它,並儘可能使用庫函數。代碼將更加便攜。 –

+0

感謝您的建議..我被困在這個問題,因爲兩天..因爲我的背景是在Java所以找到它有點困難的時候弄清楚所有這些東西..感謝您的幫助..但編譯上述代碼後,這是我得到了一個異常 - 錯誤:從類型爲cql :: cql_byte_t * {aka unsigned char *}的無效static_cast類型爲uint16_t * {aka short unsigned int *} '任何想法有什麼不對? – AKIWEB