*unsigned char
入力としてのみ受け入れる読み取り関数を使用する必要がありますが、
typedef unsigned char byte;
byte * rx_data;
rx_data = new byte [RX_PACKET_LEN*packets];
rx_data
整数(4バイト)の配列として簡単に読み取るにはどうすればよいですか?
*unsigned char
入力としてのみ受け入れる読み取り関数を使用する必要がありますが、
typedef unsigned char byte;
byte * rx_data;
rx_data = new byte [RX_PACKET_LEN*packets];
rx_data
整数(4バイト)の配列として簡単に読み取るにはどうすればよいですか?
あなたはそれをキャストすることができます:
int* pInt = reinterpret_cast<int*>( rx_data);
また
int* pInt = (int*) rx_data;
または、名前を保持したい場合は、読み取る必要があるときにキャストします。
((int*)rx_data)[0];
これは、何をしているのか完全に確信している場合にのみ行うべきであることに注意してください。そうでない場合、安全ではありません。(まあ、これはどこにでも当てはまりますが、これには特別な注意が必要です)。頭に浮かぶ何か -RX_PACKET_LEN*packets
の倍数である必要がありsizeof(int)
ます。
これは C++ であるため、reinterpret_cast を使用して unsigned char ポインターを int ポインターにキャストする必要があります。
int * data = reinterpret_cast<int*>(rx_data);
ただし、これはデータが特定のエンディアン形式で格納されていることを前提としているため、char の配列が異なるエンディアンを持つ別のプラットフォームからのものである場合、このコードは機能しません。同じプラットフォームを想定している場合は、おそらく問題ありません。
一般的な設定で唯一安全な方法は、コピーを作成することです。
std::vector<int32_t> target(RX_PACKET_LET * packets / sizeof(int32_t));
std::copy(rx_data, rx_data + RX_PACKET_LET * packets,
reinterpret_cast<unsigned char *>(target.data()));
target[0]
、target[1]
、 ... を整数として読み取ることができるようになりました。
これには memcpy を使用できます。
byte *rx_data = ...
size_t rx_data_size = ...
std::array<int, rx_data_size/sizeof(int)> data;
std::memcpy(data.get(), rx_data, data.size() * sizeof(int));
// read and modify data
// if you need to write it back out to rx_data then copy data back when you're done
std::memcpy(rx_data, data.get(), data.size() * sizeof(int));
これには、キャストが含まれず、整列されていないメモリを処理し、難解なエイリアシング規則に依存しないという利点があります。
欠点の 1 つは、データをコピーするとパフォーマンスが低下する可能性があることです。ただし、これは保証されません。最近のコンパイラは通常、memcpy をコンパイラ組み込み関数として実装しており、オプティマイザはその動作について推論できます。
LLVMを試してみたところ、次のことがわかりました。
void increment(char *buf) {
int i;
memcpy(&i,buf,sizeof(int));
++i;
memcpy(buf,&i,sizeof(int));
}
void increment(int &i) {
++i;
}
ほとんど同じ IR 表現 (clang tmp.cpp -emit-llvm -o - | opt -S -O2) とまったく同じ x86_64 アセンブリを生成します。
ポインターの型を byte* から int* に変更すると、ポインターをインクリメントする (p++) ときに、自動的に 4 バイトを読み取るか、4 バイトをジャンプします。セグメンテーション違反が発生しないように、バイト配列のサイズがモジュール 4 であることを確認してください。