3

int64_t をネットワーク バイト オーダーに変換できる次のコードを見つけました。ここで、ネットワーク バイト オーダーがリトルエンディアン マシンに変換されるように、反対のコードが必要です。コードはこれです。

int64_t decode(void* value){
    int64_t vv = *((int64_t*) value);
    int num = 42;
    if(*(char *)&num == 42) //test big/little endian
        return (((uint64)htonl(vv)) << 32) + htonl(vv >> 32);
    else 
        return vv;
}

どうもありがとう!

4

5 に答える 5

5

あなたのコードhtonll

#define htonll(x) ((((uint64_t)htonl(x)) << 32) + htonl((x) >> 32))

バイトを端から端まで反転します。2 回適用すると、値が元の状態に戻ります。したがって、同じ関数を に使用できますntohll

于 2013-05-04T14:38:03.857 に答える
0

ユニオンを使用してそれを行う方法は次のとおりです。ビットシフト方法もうまくいきますが、私見では、正しく行うのは少し難しいです。

#include<stdlib.h>
#include<stdio.h>

union MyUnion {
   int64_t i64;
   int32_t i32[2];
};

int64_t htonll(int64_t hostFormatInt64)
{
   MyUnion u;
   u.i64 = hostFormatInt64;
   int32_t temp = u.i32[0];
   u.i32[0] = htonl(u.i32[1]);
   u.i32[1] = htonl(temp);
   return u.i64;
}

int64_t ntohll(int64_t networkFormatInt64)
{
   MyUnion u;
   u.i64 = networkFormatInt64;
   int32_t temp = u.i32[0];
   u.i32[0] = ntohl(u.i32[1]);
   u.i32[1] = ntohl(temp);
   return u.i64;
}

void Test(int64_t i)
{
   printf("Testing value %lli\n", i);
   int64_t networkI = htonll(i);
   printf("   Network format is %lli (0x%llx)\n", networkI, networkI);
   int64_t hostAgainI = ntohll(networkI);
   printf("   Back to host again %lli (0x%llx)\n", hostAgainI, hostAgainI);
   if (hostAgainI != i)
   {
      printf("ERROR, we didn't get the original value back!\n");
      abort();
   }
}

int main()
{
   // A quick unit test to make sure I didn't mess anything up :)
   int64_t i = 0;
   while(1)
   {
      Test(i);
      Test(-i);
      i += rand();
   }
   return 0;
}
于 2013-05-04T14:46:55.753 に答える
0

c:\Program Files (x86)\Windows Kits\8.1\Include\um\WinSock2.h からコピー

#if !defined(NO_EXTRA_HTON_FUNCTIONS) && !defined(__midl) && (defined(INCL_EXTRA_HTON_FUNCTIONS) || NTDDI_VERSION>=NTDDI_WIN8)
/*
 * Byte order conversion functions for 64-bit integers and 32 + 64 bit 
 * floating-point numbers.  IEEE big-endian format is used for the
 * network floating point format.
 */
#define _WS2_32_WINSOCK_SWAP_LONG(l)                \
            ( ( ((l) >> 24) & 0x000000FFL ) |       \
              ( ((l) >>  8) & 0x0000FF00L ) |       \
              ( ((l) <<  8) & 0x00FF0000L ) |       \
              ( ((l) << 24) & 0xFF000000L ) )

#define _WS2_32_WINSOCK_SWAP_LONGLONG(l)            \
            ( ( ((l) >> 56) & 0x00000000000000FFLL ) |       \
              ( ((l) >> 40) & 0x000000000000FF00LL ) |       \
              ( ((l) >> 24) & 0x0000000000FF0000LL ) |       \
              ( ((l) >>  8) & 0x00000000FF000000LL ) |       \
              ( ((l) <<  8) & 0x000000FF00000000LL ) |       \
              ( ((l) << 24) & 0x0000FF0000000000LL ) |       \
              ( ((l) << 40) & 0x00FF000000000000LL ) |       \
              ( ((l) << 56) & 0xFF00000000000000LL ) )


#ifndef htonll
__inline unsigned __int64 htonll ( unsigned __int64 Value ) 
{ 
    const unsigned __int64 Retval = _WS2_32_WINSOCK_SWAP_LONGLONG (Value);
    return Retval;
}
#endif /* htonll */

#ifndef ntohll
__inline unsigned __int64 ntohll ( unsigned __int64 Value ) 
{ 
    const unsigned __int64 Retval = _WS2_32_WINSOCK_SWAP_LONGLONG (Value);
    return Retval;
}
#endif /* ntohll */

#ifndef htonf
__inline unsigned __int32 htonf ( float Value ) 
{ 
    unsigned __int32 Tempval;
    unsigned __int32 Retval;
    Tempval = *(unsigned __int32*)(&Value);
    Retval = _WS2_32_WINSOCK_SWAP_LONG (Tempval);
    return Retval;
}
#endif /* htonf */

#ifndef ntohf
__inline float ntohf ( unsigned __int32 Value ) 
{ 
    const unsigned __int32 Tempval = _WS2_32_WINSOCK_SWAP_LONG (Value);
    float Retval;
    *((unsigned __int32*)&Retval) = Tempval;
    return Retval;
}
#endif /* ntohf */

#ifndef htond
__inline unsigned __int64 htond ( double Value ) 
{ 
    unsigned __int64 Tempval;
    unsigned __int64 Retval;
    Tempval = *(unsigned __int64*)(&Value);
    Retval = _WS2_32_WINSOCK_SWAP_LONGLONG (Tempval);
    return Retval;
}
#endif /* htond */

#ifndef ntohd
__inline double ntohd ( unsigned __int64 Value ) 
{ 
    const unsigned __int64 Tempval = _WS2_32_WINSOCK_SWAP_LONGLONG (Value);
    double Retval;
    *((unsigned __int64*)&Retval) = Tempval;
    return Retval;
}
#endif /* ntohd */
#endif /* NO_EXTRA_HTON_FUNCTIONS */

使用する

Microsoft Visual Studio Professional 2015
バージョン 14.0.25420.01 Update 3
Microsoft .NET Framework
バージョン 4.7.03062

テストコード:

#include "stdafx.h"
#include <string>
#include <stdexcept>

#include <Shlwapi.h>
#pragma comment(lib, "shlwapi.lib")

int _getcharIfNeeded() {
    HWND consoleWnd = GetConsoleWindow();
    DWORD dwProcessId;
    GetWindowThreadProcessId(consoleWnd, &dwProcessId);
    if (GetCurrentProcessId() == dwProcessId)
    {
        printf("I have my own console, press enter to exit\n");
        return getchar();
    }
    else
    {
        return printf("This Console is not mine, good bye\n");
    }
}

#include <boost/algorithm/hex.hpp>
#include <boost/format.hpp>
#include <boost/format/group.hpp>
int wmain(int argc, wchar_t *argv[])
{
#define SMB_FILE_SEPARATOR_CHAR '\\'
#define OWNER_FILE_PREFIX "~$"
    std::string strFileName("\\\\10.23.57.72\\fromw12r2\\behavior\\~$tree file-editing prohibited.xlsx");
    const size_t posFileName = strFileName.find_last_of(SMB_FILE_SEPARATOR_CHAR);
    bool isOwnerFile = std::string::npos != posFileName ? 0 == strncmp(strFileName.c_str() + posFileName + 1, OWNER_FILE_PREFIX, strlen(OWNER_FILE_PREFIX)) : false;

    //https://stackoverflow.com/questions/16375340/c-htonll-and-back
//#define htonll(x) ((((uint64_t)htonl(x)) << 32) + htonl((x) >> 32))
#define HTONLL(x) ((1==htonl(1)) ? (x) : (((uint64_t)htonl((x) & 0xFFFFFFFFUL)) << 32) | htonl((uint32_t)((x) >> 32)))
#define NTOHLL(x) ((1==ntohl(1)) ? (x) : (((uint64_t)ntohl((x) & 0xFFFFFFFFUL)) << 32) | ntohl((uint32_t)((x) >> 32)))

    const char smb2_sesid_bytes[] = { 0x23, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00 };
    const uint64_t sessionId_reinterpret_bytes_in_host_order = *reinterpret_cast<const uint64_t*>(smb2_sesid_bytes);
    const uint64_t sessionId_in_network_order = htonll(sessionId_reinterpret_bytes_in_host_order);
    const std::string strHex = boost::algorithm::hex(std::string(reinterpret_cast<const char*>(&sessionId_in_network_order), sizeof(uint64_t)));

    std::ostringstream strSink;
    //https://en.cppreference.com/w/cpp/iterator/ostreambuf_iterator
    boost::algorithm::hex(std::cbegin(smb2_sesid_bytes), std::cend(smb2_sesid_bytes), std::ostreambuf_iterator<char>(strSink));
    printf(strSink.str().c_str());//std::cout << stream.str();

    printOptimizedComparison();

    std::stringstream stream; // #include <sstream> for this
    const int MaximalAccess = 0x001f01ff;
    //boost::io::group(hex, showbase, 40); //using boost::io::group;
    stream << boost::format("PID=%1% (%1$#08x), MaximalAccess=%2% (%2$#08x), 0x%3$08x\n") % GetCurrentProcessId() % MaximalAccess % 0x001f01ff;
    stream << boost::format("%08x\n") % MaximalAccess;
    printf(stream.str().c_str());//std::cout << stream.str();

    testRomanToInt("III", 3);
    testRomanToInt("IV", 4);
    testRomanToInt("IX", 9);
    testRomanToInt("LVIII", 58);
    testRomanToInt("MCMXCIV", 1994);

    //https://stackoverflow.com/questions/663449/what-is-the-best-way-to-attach-a-debugger-to-a-process-in-vc-at-just-the-right
#ifdef __DEBUG
    __debugbreak(); //__asm int 3
#endif
    //it should just silently wait until you attach your debugger to the process.
    //while (!::IsDebuggerPresent()) ::Sleep(100); // to avoid 100% CPU load

    return _getcharIfNeeded(); //return IsDebuggerPresent() && getchar();
}
于 2019-04-09T03:00:54.733 に答える