0

次のパケット レイアウトがあります。

struct PacketLayout
{
  int GateCode;
  BYTE StringLen;
  char String[StringLen];
  BYTE ServerStatus;
  BYTE ServerStorage;
  BYTE ServerNumber;
}

クラスは次のとおりです。

class ServerInfo
{
  short PacketSize;   //Size of the whole packet
  BYTE TotalServers; //total of PacketLayout structs
  PacketLayout Server[TotalServers];
  int GlobalSecCode;
  short EncryptedPacketSize; //Same as the first member, just xored
}

したがって、私が抱えている問題は、サイズがBYTE StringLen (構造体の場合) とBYTE TotalServers (クラスの場合)によってポイントされる最後のメンバーに依存するクラスまたは構造体内で可変サイズの配列を作成することです。

私はこれに対する解決策が何であるかわかりません、おそらくテンプレートを実装しますか?それなら例を見ることができますか(私はまだテンプレートに慣れていません)また、自分でポインターの位置を計算せずにメンバー名を参照したいです(私が現在やっているように)。

ありがとう。

4

3 に答える 3

2

テンプレートを使用してこれを行うことができます。たとえば、次のようになります。

template <int StringSize>
struct PacketLayout
{
  int GateCode;
  BYTE StringLen;
  char String[StringSize];
  BYTE ServerStatus;
  BYTE ServerStorage;
  BYTE ServerNumber;
};

これを次のように使用できます。

PacketLayout<100> pkt;

通常、あなたがやりたいことはもっと簡単です。たとえば、パケットの順序を変更し、サイズの上限がわかっている場合は、次のように簡単に実行できます。

struct PacketLayout
{
  int GateCode;
  BYTE StringLen;
  BYTE ServerStatus;
  BYTE ServerStorage;
  BYTE ServerNumber;
  char String[MAX_POSSIBLE_SIZE];
};

または、次のようにします。

struct PacketLayout
{
  int GateCode;
  BYTE StringLen;
  BYTE ServerStatus;
  BYTE ServerStorage;
  BYTE ServerNumber;
  char *String;
};

読み取り中に割り当て/設定Stringします。

個人的には、この厄介な低レベルの詳細をすべてスキップし、protobufのようなものを使用して作業を行い、プロジェクトに価値を付加するより重要な高レベルの事柄に自由に集中できるようにします。

時々使用される一般的だが汚いトリックもあります:

struct PacketLayout
{
  int GateCode;
  BYTE StringLen;
  BYTE ServerStatus;
  BYTE ServerStorage;
  BYTE ServerNumber;
  char String[1];
};

最後に変数部分のサイズを 1 に定義し、構造体に必要以上のメモリを故意に割り当てて、最後を超えて書き込むことができるようにします。これは悪いことであり、あまりお勧めできません。

于 2012-08-01T19:09:28.180 に答える
0

これを達成するためのC++の良い方法はありません。

これは、PacketLayoutで可変サイズの配列を作成する方法です。

struct PacketLayout
{
  int GateCode;
  BYTE StringLen;
  BYTE ServerStatus;
  BYTE ServerStorage;
  BYTE ServerNumber;
  char String[1];
}

次に、インスタンスを割り当てます。

PacketLayout* createPacketLayout(BYTE stringLen)
{
    PacketLayout* packetLayout = (PacketLayout*)new char[sizeof(PacketLayout) - 1 + stringLen];
    packetLayout->StringLen = stringLen;
    return packetLayout;
}

この場合、ServerInfoはポインターの配列を保持できます。

于 2012-08-01T19:22:44.013 に答える
0

テンプレートを使用することは間違いなく行く方法です:

template <size_t TotalServers>
class ServerInfo 
{
    PacketLayout Server[TotalServers];
    int GlobalSecCode;
};

ServerInfoこれには、1 つを別のものに割り当てることができないという欠点があるため、a を使用することstd::vectorが重要である場合は、おそらく重要です。

于 2012-08-01T19:10:11.210 に答える