2010-05-19 193 views
0

我正在學習如何使用boost精靈齊二進制的末尾解析器。我根據herebasics examples編寫了一個小測試解析器程序,但它不能正常工作。它給了我味精:「錯誤:不匹配」。Boost Binary Endian解析器不工作?

這是我的代碼。


    #include "boost/spirit/include/qi.hpp" 
    #include "boost/spirit/include/phoenix_core.hpp" 
    #include "boost/spirit/include/phoenix_operator.hpp" 
    #include "boost/spirit/include/qi_binary.hpp" // parsing binary data in various endianness

template "<"typename P, typename T> void binary_parser(char const* input, P const& endian_word_type, T& voxel, bool full_match = true) { using boost::spirit::qi::parse; char const* f(input); char const* l(f + strlen(f)); bool result1 = parse(f,l,endian_word_type,voxel); bool result2 =((!full_match) || (f ==l)); if (result1 && result2) { //doing nothing, parsing data is pass to voxel alreay } else { std::cerr << "Error: not match!!" << std::endl; exit(1); } } typedef boost::uint16_t bs_int16; typedef boost::uint32_t bs_int32; int main (int argc, char *argv[]){ namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; using qi::big_word; using qi::big_dword; boost::uint32_t ui; float uf; binary_parser("\x01\x02\x03\x04",big_word,ui); assert(ui=0x01020304); binary_parser("\x01\x02\x03\x04",big_word,uf); assert(uf=0x01020304); return 0; }

我幾乎複製的例子,但爲什麼這種二元解析器不起作用。我使用Mac OS 10.5.8和gcc 4.01編譯器。

回答

2

big_word解析器大端字(16位)相匹配,而big_dword將匹配你想要什麼(大端DWORD,32位)。但我認爲將float用作二進制解析器的屬性並不是一個好主意,您可能得不到您期望的結果。

+0

謝謝你,你是對的。我沒有得到我所期望的。那麼我應該先解析它爲無符號的32位int,然後static_cast它爲float?或者有更好的方法來完成這項工作?我是否需要將字節直接交換爲float或double? – 2010-05-21 11:14:50

+0

通常(在IEEE-754中),float和double不是endian敏感的,它們的佈局在所有架構上都是相同的。如果你需要使用Spirit輸入/輸出float和double的二進制(比特)表示,你可能需要做一些醜陋的事情:float f; * reinterpret_cast (&f);或&f);或一些令人討厭的技巧與聯盟,但現在我認爲它,我相信最好的解決方案是將bin_float和bin_double解析器/生成器添加到Spirit,目前缺少這些,我可能只寫一篇文章在Spirit網站上關於這個...... – hkaiser 2010-05-21 13:14:34

+0

你說得對,我不需要精神來處理浮點數,我在這裏找到了我的答案http://stackoverflow.com/questions/1695681/reading-from-and-寫入到最中間的一個二進制文件式-CC – 2010-05-24 14:37:28

0

我使用了錯誤的parse參數。我不應該使用的big_word代替big_dword