C での「標準」 64 ビット htonl 関数の検索
C では、 htonl 関数は 32 ビットの変換に使用されます。ホストのバイトオーダーからネットワークのバイトオーダーまでのビット整数。ただし、64 ビット整数の場合、現時点ではこの言語で使用できる「標準」 htonll 関数はありません。
htonll の移植可能な実装
このニーズに対処するには、プログラマはは、Windows、Linux、AIX などのさまざまなプラットフォーム間で 64 ビット整数のバイトオーダー変換を処理するための htonll の移植可能な実装を考案しました。そのような実装の 1 つは次のとおりです。
<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>
この実装は、32 ビット変換に htonl 関数を使用し、それを 2 回 (64 ビット整数の 32 ビット半分ごとに 1 回ずつ) 適用します。また、スワップされたデータも保証します。パーツは正しい順序になっています。
エンディアンの決定
C にはコンパイル時にエンディアンを決定する移植可能な方法がないため、上記の実装は実行時に呼び出してエンディアンをチェックします。 htonl を整数 1 に計算します。結果が 1 に等しい場合、システムはリトルエンディアンであり、バイト スワップは必要ありません。それ以外の場合、それはビッグエンディアンであり、実装はバイトを交換します。
コンパイラ ディレクティブを使用する代替方法
別の移植可能な実装では、コンパイラ ディレクティブを使用して、ビッグ エンディアンとビッグ エンディアンを区別します。リトルエンディアン アーキテクチャ:
<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>
この実装は、ほとんどのコンパイラとオペレーティング システムでサポートされている BIG_ENDIAN ディレクティブに基づいて htonll 関数と ntohll 関数を定義します。
以上がC で 64 ビット htonll 関数を実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。