2

char の 64 バイト配列 (USB 経由で渡される) を受け取る C プログラムがあります。最初のバイト (コマンドの種類を示す) に応じて、コードをより明確にするために、char 配列に構造を「課す」必要があります。

たとえば、コマンド コードが 10 の場合、次のようになります。

struct
{
    uint8_t commandNumber;
    uint16_t xPos;
    uint16_t yPos;
    int32_t identificationNumber;
 } commandTen;

したがって、char packet[64] 'onto' commandTen をキャストし、次のようなものを使用してフィールドにアクセスしたいと思います。

localVar = commandTenPacket->xPos;

これはCでどのように達成できますか?

前もって感謝します!

4

3 に答える 3

8

まず、他の人が言ったように、structパディングがないことを確認する必要があります。あなたのコンパイラにはおそらくそのための拡張機能があり#pragma packます。

struct例のように変数ではなく、ユースケースごとに定義します。

次に、union

typedef union overlay overlay;

union overlay {
 uint8_t raw[64];
 struct type10 command10;
 struct type42 command42;
};

そのタイプのバッファを作成します

overlay buffer;

データを受け取る関数に「生の」部分をフィードしますgetit(buffer.raw)。その後

switch (buffer.raw[0]) {
 case 10: {
   // use buffer.command10
   break;
 }
 case 42: {
   // use buffer.command42
 }
}

すべてをuint8_tAKAとして読み取っているため、これは C 標準によって適切に機能することが保証されていますunsigned char。実際、unions の主な使用例は、まさにこの種の「型のパニング」です。さまざまなタイプの IPv4、IPv6 などのアドレスを持つネットワーク層全体が同様の方法で機能します。

于 2012-08-19T07:40:46.310 に答える
1

キャストしないでください。使用するmemcpy

char packet[64];
...

assert(sizeof commandTen <= sizeof packet);
memcpy(&commandTen, packet, sizeof commandTen);

これは、サイズとメモリ レイアウトが適切に一致していることを前提としています (キャストベースのソリューションが使用するのと同じ前提です)。

于 2012-08-19T07:43:52.450 に答える
0

ポインターを使用する方法があります。このように説明してみましょう。

struct commandX {
   int x;
};
struct commandMessage {
   char[8] msg;
};

char* message = (char*) malloc(sizeof(char)*9); // this will allow us a struct 
                                                // size of 8 bytes, since the
                                                // first byte will store the
                                                // information on how to inter-
                                                // the memory (or you do it in
                                                // a different way).
// 1. determine your offset
//    in this case, it would be the length of the command on how to interpret.
//    basically, it has to be the count of bytes from the
//    beginning of your message to the start of your struct
int offset = sizeof(char) * 1;
// 2. read the command (that would be: message[0])
// 3. now get rid of the type information, so that you can address every byte
void* temp = (void*) message;
// 4.1 if it is commandX:
struct commandX *x_temp = (struct commandX*) (temp+offset);
    // use x_temp->x
// 4.2 if it is commandMessage:
struct commandMessage *msg_temp = (struct commandMessage*) (temp+offset)
   // use msg_temp->msg
于 2012-08-19T07:41:03.393 に答える