私は最近、Stack Overflowで、16ビット整数からデータをキャストし、その後に未定の量のvoid*キャストメモリを既知のソケットライブラリを使用するためにunsignedcharsのstd::vectorにキャストする方法について質問しました。署名が次のような関数を使用して生データを送信するNetLinkとして:
void rawSend(const vector<unsigned char>* data);
(参考のために、ここにその質問があります:unsigned int +文字列をunsignedcharベクトルにキャストします)
質問への回答に成功し、回答してくださった方々に感謝いたします。Mike DeSimoneは、データをNetLinkが受け入れる形式(std :: vector)に変換するsend_message()関数の例で応答しました。これは次のようになります。
void send_message(NLSocket* socket, uint16_t opcode, const void* rawData, size_t rawDataSize)
{
vector<unsigned char> buffer;
buffer.reserve(sizeof(uint16_t) + rawDataSize);
buffer.push_back(opcode >> 8);
buffer.push_back(opcode & 0xFF);
const unsigned char* base(reinterpret_cast<const unsigned char*>(rawData));
buffer.insert(buffer.end(), base, base + rawDataSize);
socket->rawSend(&buffer);
}
これはまさに私が必要としていたもののように見えるので、付随するreceive_message()関数の作成に着手しました...
...しかし、私はすべてのビットシフトなどを完全には理解していないと言うのが恥ずかしいので、ここで壁にぶつかりました。私が過去10年近くに書いたすべてのコードでは、ほとんどのコードは高級言語で書かれており、残りのコードは実際には低レベルのメモリ操作を要求していません。
receive_message()関数の記述に戻ると、ご想像のとおり、私の出発点はNetLinkのrawRead()関数であり、その署名は次のようになります。
vector<unsigned char>* rawRead(unsigned bufferSize = DEFAULT_BUFFER_SIZE, string* hostFrom = NULL);
私のコードは次のように始まります。
void receive_message(NLSocket* socket, uint16_t* opcode, const void** rawData)
{
std::vector<unsigned char, std::allocator<unsigned char>>* buffer = socket->rawRead();
std::allocator<unsigned char> allocator = buffer->get_allocator(); // do I even need this allocator? I saw that one is returned as part of the above object, but...
// ...
}
rawRead()を最初に呼び出した後、ベクターを反復処理し、ベクターからデータを取得してビットシフト操作を元に戻し、データを*rawDataと*opcodeに返す必要があるようです。繰り返しになりますが、私はビットシフトにあまり精通していません(構文を理解するためにグーグルを実行しましたが、上記のsend_message()コードがシフトを必要とする理由をまったく理解していません)。ここ。
誰かがこの付随するreceive_message()関数の書き方を理解するのを手伝ってもらえますか?ボーナスとして、誰かが元のコードを説明して、将来的にそれがどのように機能するか(特に、この場合のシフトがどのように機能し、なぜそれが必要なのか)を知ることができれば、それは将来の私の理解を深めるのに役立ちます。
前もって感謝します!