私のJava指定されたintのバイト配列を返すコードにこのメソッドがあります:
private static byte[] intToBytes(int paramInt)
{
byte[] arrayOfByte = new byte[4];
ByteBuffer localByteBuffer = ByteBuffer.allocate(4);
localByteBuffer.putInt(paramInt);
for (int i = 0; i < 4; i++)
arrayOfByte[(3 - i)] = localByteBuffer.array()[i];
return arrayOfByte;
}
誰かがそのメソッドをC++に変換する方法を教えてもらえますか?
std::vector<unsigned char>
を使用:
#include <vector>
using namespace std;
vector<unsigned char> intToBytes(int paramInt)
{
vector<unsigned char> arrayOfByte(4);
for (int i = 0; i < 4; i++)
arrayOfByte[3 - i] = (paramInt >> (i * 8));
return arrayOfByte;
}
これには関数全体は必要ありません。単純なキャストで十分です:
int x;
static_cast<char*>(static_cast<void*>(&x));
C++のオブジェクトは、バイトの配列として再解釈できます。実際にバイトのコピーを別の配列に作成する場合は、std::copy
を使用できます。
int x;
char bytes[sizeof x];
std::copy(static_cast<const char*>(static_cast<const void*>(&x)),
static_cast<const char*>(static_cast<const void*>(&x)) + sizeof x,
bytes);
これらのメソッドはどちらもバイトの順序を考慮しませんが、int
をバイトの配列として再解釈できるため、必要な変更を自分で行うのは簡単です。
私が使用する別の便利な方法は、ユニオンです:
union byteint
{
byte b[sizeof int];
int i;
};
byteint bi;
bi.i = 1337;
for(int i = 0; i<4;i++)
destination[i] = bi.b[i];
これにより、バイト配列と整数が「重複」するようになります(同じメモリを共有します)。これは、バイト配列がタイプと同じサイズである限り、すべての種類のタイプで実行できます(そうでない場合、フィールドの1つは他のフィールドの影響を受けません)。また、整数操作とバイト操作/コピーを切り替える必要がある場合にも、それらを1つのオブジェクトとして持つと便利です。
バイトからバイトへ、またはその逆
unsigned char bytes[4];
unsigned long n = 1024;
bytes[0] = (n >> 24) & 0xFF;
bytes[1] = (n >> 16) & 0xFF;
bytes[2] = (n >> 8) & 0xFF;
bytes[3] = n & 0xFF;
printf("%x %x %x %x\n", bytes[0], bytes[1], bytes[2], bytes[3]);
int num = 0;
for(int i = 0; i < 4; i++)
{
num <<= 8;
num |= bytes[i];
}
printf("number %d",num);
std::vector<unsigned char> intToBytes(int value)
{
std::vector<unsigned char> result;
result.Push_back(value >> 24);
result.Push_back(value >> 16);
result.Push_back(value >> 8);
result.Push_back(value );
return result;
}
Andingおよびshift操作で個々のバイトを取得できます。
byte1 = nint & 0x000000ff
byte2 = (nint & 0x0000ff00) >> 8
byte3 = (nint & 0x00ff0000) >> 16
byte4 = (nint & 0xff000000) >> 24
Int(またはその他のデータ型)は、メモリにバイトとして既に格納されています。では、なぜメモリを直接コピーしないのですか?
memcpy(arrayOfByte, &x, sizeof x);
他のデータ型でも機能するシンプルでエレガントなライナー。
バイトを逆にする必要がある場合は、std :: reverseを使用できます。
memcpy(arrayOfByte, &x, sizeof x);
std::reverse(arrayOfByte, arrayOfByte + sizeof x);
またはもっと良いのは、単にバイトを逆方向にコピーして開始することです
BYTE* p = (BYTE*) &x;
std::reverse_copy(p, p + sizeof x, arrayOfByte);
データのコピーをまったく作成せず、そのバイト表現のみを使用する場合
BYTE* bytes = (BYTE*) &x;
return ((byte[0]<<24)|(byte[1]<<16)|(byte[2]<<8)|(byte[3]));
:D
私が助けてくれるといいのですが
template <typename t_int>
std::array<uint8_t, sizeof (t_int)> int2array(t_int p_value) {
static const uint8_t _size_of (static_cast<uint8_t>(sizeof (t_int)));
typedef std::array<uint8_t, _size_of> buffer;
static const std::array<uint8_t, 8> _shifters = {8*0, 8*1, 8*2, 8*3, 8*4, 8*5, 8*6, 8*7};
buffer _res;
for (uint8_t _i=0; _i < _size_of; ++_i) {
_res[_i] = static_cast<uint8_t>((p_value >> _shifters[_i]));
}
return _res;
}
この質問にはすでに答えがありますが、この問題の解決策を示します。テンプレート関数と整数制約を使用しています。
私の解決策は次のとおりです。
#include <type_traits>
#include <vector>
template <typename T,
typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
std::vector<uint8_t> splitValueToBytes(T const& value)
{
std::vector<uint8_t> bytes;
for (size_t i = 0; i < sizeof(value); i++)
{
uint8_t byte = value >> (i * 8);
bytes.insert(bytes.begin(), byte);
}
return bytes;
}