0

SCPI パーサーを (lib として) コーディングしています。lib ユーザーによるデバイスまたはアプリケーション関数は、複数の結果を複数のタイプで出力できる必要があります (タイプ A の複数の結果またはタイプ B の複数の結果の混合タイプではありません)。

最初に、実行制御によってデバイス関数に渡される void ポインターの配列について調べました (デバイス関数が のようなものである場合unsigned int deviceFunction (double inArg1, bool inArg2, void ** outResults);)。私の応答フォーマッタが結果データを見ると、どのタイプにキャストするかわかりません。

https://stackoverflow.com/a/3852192/1292918と同様に、ユニオンと構造体の使用を検討しましたが、デバイス関数が複数の結果を報告する必要がある場合にこれが最善の方法であるかどうかはわかりません。

たぶん、私の考えがぐちゃぐちゃになってしまったのかもしれません。これを行うための一般的な方法やイディオムはありますか?

(これはC++ ではなくC であることに注意してください)

4

4 に答える 4

2

unionEric のコメントに基づいて、複雑な構造体を返すためにan を使用する次のコードを思いつきました。この場合、前述の「エイリアシング ルール」エラーは発生しません。

struct Result {
  int type;
};

struct Data1
{
  int type;
  char* str;
  int val;
};

struct Data2 {
  int type;
  int arr[4];
};

union StructTestUnion
{
  struct Result res;
  struct Data1 data1;
  struct Data2 data2;
};

union StructTestUnion getRandomResult(void) {
  static int cnt = 0;
  union StructTestUnion resVal;
  switch (cnt) {
    case 0:
      resVal.data1.type = 1;
      resVal.data1.str = "struct data 1";
      resVal.data1.val = 123;
      break;
    case 1:
      resVal.data2.type = 2;
      resVal.data2.arr[0]=1;
      resVal.data2.arr[1]=2;
      resVal.data2.arr[2]=3;
      resVal.data2.arr[3]=4;
      break;
  }
  cnt++;
  if (cnt==2) cnt = 0;

  return resVal;
}

int main() {
  union StructTestUnion resVal;

  int a =0;
  for (a =0; a<4; a++) {
    resVal = getRandomResult();
    printf("%d: %d ", a, resVal.res.type);
    switch ( resVal.res.type ) {
      case 1:
        printf("str=[%s] val=[%d]\n", resVal.data1.str, resVal.data1.val);
        break;
      case 2:
        printf("arr=[%d,%d,%d,%d]\n",resVal.data2.arr[0], resVal.data2.arr[1],resVal.data2.arr[2], resVal.data2.arr[3]);
        break;
    }
  }
  return 0;
}
于 2013-05-20T13:18:20.140 に答える
1

ダブルポインターは引き続き使用できvoidますが、呼び出し元に実際にどの型が含まれているかを伝える方法を見つける必要があります。たとえば、 を使用して関数から返すか、return別の参照型パラメータ ( int *outResultsType.

次に、データを正しく使用するために呼び出し元に任せます。

于 2013-05-20T12:29:20.417 に答える
0

次のような一般的な構造を作成できます。

struct Generic {
  int type;
}

およびデータを含むいくつかの実際の戻り構造体ですが、最初のフィールドは変更されていません。

struct Data1 {
  int type; // == TYPE_DATA1 == 1
  char* aCharVal;
  double aDoubleVal;
}

struct Data2 {
  int type; // == TYPE_DATA2 == 2
  int* anArray;
  int arraySize;
}

そうすれば、構造を返し、 としてキャストしstruct Generic、タイプをチェックして、さらに先に進むことができます。

この方法の問題点の 1 つは、「逆参照型のパニングされたポインターが厳密なエイリアス規則に違反する」ことです。

于 2013-05-20T12:45:25.487 に答える