質問

ように実装では、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;
}

警告:未テストコード!してください使用する前にテストます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top