-2

この質問に適切なタイトルを付ける方法が本当にわかりません。申し訳ありません。

このすべての目的が何であるかを知るために: uint8_t 変数ポインターを bar() に渡します。これにより、1 または 0 に設定され、メイン内の状態を確認できます。zbar() が必要です。これはスレッドであり、実際に値を 1 または 0 に設定します

だから私はどこかに持っています:

struct foo_t {
    ...
    uint8_t *state;
};

そして主に私は一緒に行きます:

int main(void) {
     uint8_t state = 0;
     bar(&state);

     while(1) {
          if(state)
              //do something here
     }
}

ここには、別のソースファイルの別の場所があります。

void bar(uint8_t *state) {
    struct foo_t *foo;    //using malloc here - don't worry

    foo->state = state;

    zbar(foo); 

}

void zbar(struct foo_t *arg) {
    if(condition)
       arg->state = 1;
    else
       arg->state = 0;
 }

これを機能させる方法は?o0 zBar は実際には arg 構造体にアクセスできますが、それはまったく問題ではありません。

スレッド内などで使用されているので、なぜそんなに奇妙にしているのか心配しないでください。

4

4 に答える 4

2

あなたが言っていることは次のとおりだと思います。

  • スレッド 1 は を実行mainし、ローカル変数を持っていますuint8_t state
    • このローカル変数の値をループでチェックします。zbar
  • スレッド 2 が実行されます (とりわけ)zbar
    • zbarの値を変更するとき、スレッド 1 で新しい値を確認しarg->stateたいmain

arg->stateしたがって、まず、とmainのローカルstate変数が実際にメモリ内の同じ場所を参照していることを確認する必要があります。barはすでに を割り当てているのでfoo_t arg、共有コピーを作成する方が簡単かもしれません:

int main(void) {
    foo_t *arg = bar();

    while(1) {
        if(arg->state)
            ; //do something here
    }
}

main次に、 が実際にその場所で新しい値を認識していることを確認する必要があります。事実が言うように、これを妨げる可能性のあることがいくつかあります。最も明白なのは、 の最初の呼び出しの後に の値を再ロードするmain必要がないということです。statebar

このようなものは本質的に移植性がありません。プラットフォームを教えてください。より多くの情報を提供できます。

于 2012-06-07T16:11:14.130 に答える
2

私はあなたが意味したと思いますvoid bar(uint8_t* state)か?

あなたが意図したと思うことはしません。state繰り返しますが、変数を変更したいと思いますmainか? もしそうなら試してみてください

struct foo_t {
    uint8_t* state; // changed this to a pointer type.
}

void bar(uint8_t* state) {
    struct foo_t *foo = blah blah;
    foo->state = state;
    zbar(foo);
}

void zbar(foo_t* arg) {
   if (condition)
       *(arg->state) = 1;
   else
       *(arg->state) = 0;
}

これがあなたがやろうとしていることだと思います

于 2012-06-07T15:59:26.617 に答える
2

bar()ポインターを介してパラメーターを取得する必要があります。また、 で状態を確認したい場合は、呼び出し後mainに指す先を変更する必要があります。boolzBar

void bar(uint8_t* state) {
  struct foo_t *foo; //using malloc here - don't worry
  foo->state = *state;
  zbar(foo);
  *state = foo->state;
}

main( bar(&state);)で正しく呼び出しています

このコードの現在の方法は、一度zbar呼び出されると、state二度と変更されないことに注意してください。スレッドに状態へのアクセス (および変更) をさせたい場合は、アドレスを に保存する必要がありますstruct foo

struct foo
{
  // ...
  uint8_t* state;
};

そして変更bar

void bar(uint8_t* state) {
  struct foo_t *foo; //using malloc here - don't worry
  foo->state = state; // no dereferencing
  // zbar(foo);  // start the thread using zbar
}

void zbar(struct foo_t *arg) {
  if(condition)
    *(arg->state) = 1;
  else
    *(arg->state) = 0;
}

次に、への変更はすべて変更され*(foo->state)ますstatemain

于 2012-06-07T15:53:54.570 に答える
1

いいえ、これはうまくいきません。まず第一に、それはコンパイルされません --foo_tstateメンバーは a であると定義されてuint8_tいますが、そこに a を格納しようとしてuint8_t *います。barのようなものを作成してこれを修正すると、の変数へのポインターが渡されますが、それで行うことは一度逆参照して結果を構造体に入れることだけであるfoo->state = *stateため、それでも機能しません。barmainstate

メンバーfoo_tを持つことを宣言し、からに渡し、それをに格納できます。または (コードの構造が許す場合) を完全に忘れて、 toからtoへのポインターを渡すだけです。つまり、次のいずれかです。uint8_t *&statemainbarfoo_tfoo_tstatemainbarzbar

struct foo_t { ...; uint8_t * state; ... };
void bar(uint8_t * state) { struct foo_t * foo; ...; foo->state = state; zbar(foo); ... }
void zbar(struct foo_t * arg) { ...; *(arg->state) = 1; ... }

[追加するために編集: この場合、別のスレッドがその値を変更する可能性があることをコンパイラに警告するためstateに、 volatileを宣言する必要もあります。]main

また

void bar(uint8_t * state) { ...; zbar(state); ... }
void zbar(uint8_t * state) { ...; *state = 1; ... }

もう1つの発言。「スレッド内などで使用されます。」奇妙なことや醜いことをする正当な理由にはなりません。あなたがスレッドで行っている特定のことがそれを必要とする特定の理由がある場合、もちろんそれは別の問題であり、もちろんあなたはここであなたの設計上の決定を擁護する義務はありません.奇妙なことをするための一般的なライセンスとして。

于 2012-06-07T15:54:29.453 に答える