2010-10-06 81 views
7

我的程序庫需要讀入big-endian整數(4字節)並將它們轉換爲主機的endian順序進行處理。雖然* nix ntohl已經在Windows下使用ntohl要求使用Ws2_32.dll(Winsock)。使用CMake檢測字節順序

這樣的依賴關係是我寧願消除的依賴關係。最簡單的做法似乎是編寫我自己的端到端交換函數(一個簡單的練習,考慮到性能並不是真正關心的問題)。但是,這需要一種方法來確定我的庫正在編譯的系統的字節序(因此我可以在大端系統上交換功能)。

由於好像沒有標準的預處理器定義,所以看起來好像有必要使用我的編譯系統(cmake)來確定它。做這件事的最好方法是什麼? (我厭倦了'編譯一個測試文件,看'類型的解決方案,因爲它們似乎會禁止交叉編譯。)

+3

注僅支持:CMake的實際上有交叉編譯合理的支持。對於需要運行測試程序的檢查,它會構建測試程序,然後等待您將高速緩存變量設置爲正確的結果。請參閱http://www.paraview.org/Wiki/CMake_Cross_Compiling。對於關注交叉編譯有點讚賞。 – 2010-10-08 00:20:00

回答

6

編輯:我看到cmake有一個TestBigEndian.cmake腳本,但它會編譯和測試運行看看系統是不是Big Endian,這不是你想要做的。

你可以在你自己的程序中用這樣的函數檢查系統的字節順序。

bool isLittleEndian() 
{ 
    short int number = 0x1; 
    char *numPtr = (char*)&number; 
    return (numPtr[0] == 1); 
} 

基本上創建一個整數,並讀取其第一個字節(最低有效字節)。如果該字節是1,那麼系統是小端,否則是大端。

但是,這不允許您直到運行時才確定字節序。

如果您想要確定系統字節序的編譯時間,除了'構建測試程序然後編譯我的真實程序',或者對編譯器定義的特定宏進行徹底檢查之外,例如GCC 4.x上的__BIG_ENDIAN__

已更新作爲示例,您可能還想看看Boost自己的endian.hpphttp://www.boost.org/doc/libs/1_43_0/boost/detail/endian.hpp

+0

「但是,這不允許您直到運行時才確定字節序。」 - 你可以做這樣的事情,它應該在編譯時進行評估: const bool g_isLittleEndian = isLittleEndian(); – darklon 2015-12-31 15:26:52

+0

@darklon'const'變量在編譯時並不嚴格評估。它可以並將在運行時進行評估,因爲'isLittleEndian()'使用變量。爲了在編譯時嚴格評估,應該使用關鍵字'constexpr'或模板元編程技術。 (之所以我認爲'const bool g_isLittleEndian = isLittleEndian();'是因爲'(char *)(&number)'不是一個常量表達式,因此在你聲明'numPtr'時, 'constexpr') – minary 2017-05-20 08:07:45