がある"標準"htonlように機能を64ビット整数をC++?
-
26-09-2019 - |
質問
ように実装では、memcacheプロトコル、ポイントを使用して64ビット整数値です。これらの値を保持する"ネットワークバイトができたのである。
いもありました uint64_t htonll(uint64_t value)
機能の変化が、残念ながら、場合には存在しないのにそれを見いだすのです。
いて1または2の質問:
- はありま 携帯 (Windows、Linux、エクス)の標準機能するのか?
- が無い場合にはそのような機能、あなたは何点ぐらいになると思を実装するのですか?
いて基本的な実装がわからないかチェックをendiannessコンパイル時にコードました。ではどのようなこ)
お願い致します。
こちらは最終的な解決に書いたのは、Brianいます。
uint64_t htonll(uint64_t value)
{
// The answer is 42
static const int num = 42;
// Check the endianness
if (*reinterpret_cast<const char*>(&num) == num)
{
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;
}
}
解決
あなたはおそらく、私はそれはかなりどこでもサポートされていますが、私は、標準的にそれを呼び出すことはありませんだと思うbswap_64
を探しています。
あなたは簡単に、1の値をint型を作成char*
としてあなたのintのアドレスをキャストし、最初のバイトの値をチェックすることにより、エンディアンをチェックすることができます。
int num = 42;
if(*(char *)&num == 42)
{
//Little Endian
}
else
{
//Big Endian
}
あなたもスワップを行う簡単な関数を作ることができ、これを知っています。
<時間>また、常にポータブルクロスプラットフォームですエンディアンのマクロが含まれているブーストを使用することができます。
他のヒント
#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))
ハードウェアアーキテクチャは、バイトスワッピングをrequres場合試験(1 == htonl(1))は、単純に(残念ながら、実行時)を決定します。我々はそれがこのような状況になるほどポータブルである、「htonl」使用に頼るので、アーキテクチャが何であるかをコンパイル時に決定する任意のポータブルな方法がありません。バイトスワッピングが必要な場合、我々は、(同様に2つの32ビットワードをスワップする思い出し)htonlを使用して、一度に32ビットを入れ替える。
<時間>ここではほとんどのコンパイラおよびAIX、BSD系、Linux、およびSolarisなどのオペレーティングシステム、間で移植されスワップを実行する別の方法があります。
#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
重要な部分は、__BIG_ENDIAN__
または__LITTLE_ENDIAN__
を使用することです。そしてない__BYTE_ORDER__
、__ORDER_BIG_ENDIAN__
または__ORDER_LITTLE_ENDIAN__
。いくつかのコンパイラおよびオペレーティングシステムは__BYTE_ORDER__
や友人に欠けます。
あなたはuint64_t htobe64(uint64_t host_64bits)
&で試すことができます
その逆のためuint64_t be64toh(uint64_t big_endian_64bits)
。
これはCで動作するようです。私は何も間違っをしましたか?
uint64_t htonll(uint64_t value) {
int num = 42;
if (*(char *)&num == 42) {
uint32_t high_part = htonl((uint32_t)(value >> 32));
uint32_t low_part = htonl((uint32_t)(value & 0xFFFFFFFFLL));
return (((uint64_t)low_part) << 32) | high_part;
} else {
return value;
}
}
のオーバーヘッドを低減するために、「もしnumは== ...」 プリプロセッサの定義を使用する:
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#else
#endif
編集:結合2つ(Brianのコードを使用):
uint64_t htonll(uint64_t value)
{
int num = 42;
if(*(char *)&num == 42)
return (htonl(value & 0xFFFFFFFF) << 32LL) | htonl(value >> 32);
else
return value;
}
警告:未テストコード!してください使用する前にテストます。