2

私のC++プロジェクトには、任意のサイズのバッファがあり、Bluetoothで満たされています。着信メッセージの形式は、0x43 0x0B 0x00 0x06 0xA2 0x03 0x03 0x00 0x01 0x01 0x0A 0x0B 0x0B 0xE6 0x0Dのようになり、0x43で始まり0x0Dで終わります。つまり、バッファがいっぱいになるたびに、上記のメッセージ形式に従って内容の順序が異なる可能性があることを意味します。

static const int BufferSize = 1024;
byte buffer[BufferSize];
  1. このバッファ内の着信メッセージを解析するための最良の方法は何ですか?
  2. 私はJavaと.NETから来たので、抽出された各メッセージをオブジェクトとして作成するための最良の方法は何ですか?クラスは解決策になる可能性がありますか?
  3. 次のようにバッファを解析するための別のクラスを作成しましたが、正しい方向に進んでいますか?

#include<parsingClass.h>
class A
{
   parsingClass ps;
public:
   parsingClass.parse(buffer, BufferSize);
}
4

4 に答える 4

2

'ProtocolUnit'クラスのメソッドとしてパーサーを使用できますか?このメソッドは、パラメーターとしてバッファーポインター/長さを取り、完全なプロトコルユニットを正しくアセンブルする前にバッファーから消費したバイト数を示すintを返すか、次のバッファーからさらにバイトが必要な場合は-1を返します。

完全なProtocolUnitができたら、それを使ってやりたいことを実行し(たとえば、処理スレッドにキューイングする)、残りのバイト/次のバッファー用に新しいものを作成できます。

于 2012-10-18T12:57:52.347 に答える
2
class ReturnMessage{
    char *message; 
    public:
    char *getMessage(unsigned char *buffer,int count){
         message = new char[count];
         for(int i = 1; i < count-2; i++){
            message[i-1] = buffer[i];
         }
         message[count-2] = '\0';
         return message;
    }
};
class ParserToMessage{
static int BufferSize = 1024;
unsigned char buffer[BufferSize];
unsigned int counter;
public:
  static char *parse_buffer()
  {
     ReturnMessage rm;
     unsigned char buffByte;
     buffByte = blueToothGetByte(); //fictional getchar() kind of function for bluetooth
     if(buffByte == 0x43){
        buffer[counter++] = buffByte;
        //continue until you find 0x0D
        while((buffByte = blueToothGetByte()) != 0x0D){
            buffer[counter++] = buffByte;
        }
     }
     return rm.getMessage(buffer,counter);
   }
};
于 2012-10-18T12:29:29.433 に答える
1

私のC++プロジェクトには、任意のサイズのバッファーがあります

私が最初に気付くのは、バッファーサイズをハードコーディングしていることです。指定したサイズよりも大きいデータをバッファに読み込もうとすると、バッファオーバーフローの危険があります。

可能であれば、バッファサイズを動的に保ち、バッファに受信するデータのサイズに応じてバイト配列を作成します。バイト配列を作成する前に、バイト配列が存在するオブジェクトに着信バッファサイズを通知してみてください。

int nBufferSize = GetBufferSize();
UCHAR* szByteArray = new UCHAR[nBufferSize];

このバッファ内の着信メッセージを解析するための最良の方法は何ですか?

パーサークラスを作成して使用しているという点で、あなたは正しい方向に進んでいます。memcpyを使用して、個々のデータ項目を一度に1つずつ、バッファーから選択した変数にコピーすることをお勧めします。この時点であなたの意図のより広い文脈を知らないので、私はそれに多くを加えることができません。

私はJavaと.NETから来たので、抽出された各メッセージをオブジェクトとして作成するための最良の方法は何ですか?クラスは解決策になる可能性がありますか?

バッファーから読み取るデータの複雑さと計画に応じて、クラスまたは構造体を使用できます。他のオブジェクトにサービスを提供するこのデータを使用してオブジェクトを作成する必要がない場合は、構造体を使用できます。構造体は、ニーズがそれほど複雑でない場合に最適です。そのため、クラス全体がやり過ぎになる可能性があります。

次のようにバッファを解析するための別のクラスを作成しましたが、正しい方向に進んでいますか?

そう思います。

それが初心者の助けになることを願っています!

于 2012-10-18T12:53:22.210 に答える
1

「これをどのように解析する必要があるか」という質問は、データをどのように解析するかによって大きく異なります。あなたの質問には2つのことが欠けています:

  1. 正確にどのようにデータを受け取りますか?あなたはBluetoothについて言及していますが、プログラミング媒体は何ですか?ソケットから読んでいますか?他の種類のAPIはありますか?一度にバイト単位で受信しますか、それともブロック単位で受信しますか?
  2. 受け取ったデータを処理するためのルールは何ですか?ほとんどのデータは、何らかの方法で、または固定フィールド長で区切られています。あなたの場合、それはどんな長さでもよいとあなたは言います、しかしあなたがそれをどのように解析したいかを説明しない限り、私は助けることができません。

私が行う1つの提案は、使用するバッファーのタイプを変更することstd::vectorです。

std::vector<unsigned char> buffer(normalSize)

normalSize着信メッセージの最も頻繁に観察されるサイズに近いものを選択する必要があります。ベクトルはアイテムをプッシュするにつれて大きくなるため、作成した配列とは異なり、大きなメッセージを受け取った場合にバッファオーバーランを心配する必要はありません。ただし、カバーの下で上に行くnormalSizeと、ベクトルは拡張要件に対処するのに十分なメモリを再割り当てします。これは高額になる可能性があるため、あまり頻繁に実行したくない場合があります。

配列とほぼ同じ方法でベクトルを使用します。主な違いの1つは、実行中のポインターを保持する必要がなく、単純に要素をベクトルの最後にプッシュできることです。したがって、Bluetoothソースから一度に1つのintを受け取ったとすると、コードは次のようになります。

// Clear out the previous contents of the buffer.
buffer.clear();

int elem(0);
// Find the start of your message. Throw away elements
// that we don't need.
while ( 0x43 != ( elem = getNextBluetoothInt() ) );

// Push elements of the message into the buffer until
// we hit the end.
while ( 0x0D != elem )
{
    buffer.push_back( elem );
}
buffer.push_back( elem ); // Remember to add on the last one.

主な利点は、プッシュされる文字数が10または10,000であるかどうかに関係なく、配列がベクトルのサイズを自動的に変更することです。

于 2012-10-18T13:15:43.283 に答える