C での 64 ビット整数のネットワーク バイト オーダー変換の移植性に関する懸念
C では、64 ビット整数を変換する必要が生じますmemcache プロトコルの実装など、特定のアプリケーションの「ネットワーク バイト オーダー」に変換します。 32 ビット整数を変換するための htonl() 関数が存在するにもかかわらず、64 ビット整数用の同様の関数 (htonll()) は依然として見つかりません。
標準関数の考慮事項
残念ながら、現在、C には 64 ビットのネットワーク バイト オーダー変換を実行できる移植可能な標準関数はありません。この欠落により、カスタム実装が必要になります。
カスタム実装
htonll() を実装するには、まずシステムのエンディアンを決定する必要があります。信頼できる方法の 1 つは、実行時に既知のバイト順序 (例: 42) を使用して整変数の値を評価することです:
<code class="cpp">static const int num = 42; bool isBigEndian = (*reinterpret_cast<const char *>(&num) == num);</code>
次に、エンディアンに従って変換を実行できます:
<code class="cpp">uint64_t htonll(uint64_t value) { if (isBigEndian) { const uint32_t high_part = htonl(static_cast<uint32_t>(value >> 32)); const uint32_t low_part = htonl(static_cast<uint32_t>(value & 0xFFFFFFFFLL)); return (static_cast<uint64_t>(low_part) << 32) | high_part; } else { return value; } }
移植性のためのマクロ
また、マクロを使用すると、htonll() とその対応物である ntohll() を定義する簡潔な方法を提供できます。
<code class="cpp">#define htonll(x) ((1 == htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) #define ntohll(x) ((1 == ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))</code>
これらマクロは、システム固有のバイト順序動作に依存して、必要なバイト スワッピングを決定します。
コンパイラ固有のマクロ
一部のコンパイラとオペレーティング システムは、エンディアンを決定するための特定のマクロを提供しています。 。たとえば、これをサポートするシステムでは、以下を使用できます。
<code class="cpp">#if __BIG_ENDIAN__ # define htonll(x) (x) # define ntohll(x) (x) #else # define htonll(x) (((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) # define ntohll(x) (((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) #endif</code>
これらの手法を採用することで、htonll() と ntohll() のカスタム実装をさまざまなシステムやコンパイラ間で移植可能にすることができます。
以上がC で 64 ビット整数をネットワーク バイト オーダーに変換するときに移植性を実現するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。