-2

我真的不知道如何给这个问题起一个好的标题——对不起。

只是想知道这一切的目标是什么:将一个 uint8_t 变量指针传递给 bar() ,它确实将它设置为 1 或 0,我可以检查它在我的 main 中的状态。我确实需要 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

bar()需要通过指针获取其参数。另外,如果要检查 中的状态main,则需要bool在调用后更改指向zBar

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 回答
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

觉得你说的是:

  • 线程 1 运行main,并且有一个局部变量uint8_t state
    • 它将在一个循环中检查这个局部变量的值,期望它可能被异步更新zbar
  • 线程 2 运行(除其他外)zbar
    • zbar更改 的值时arg->state,您希望main在线程 1 中查看新值

因此,首先,您需要确保arg->statemain的局部state变量实际上引用了内存中的同一位置。由于bar已经 allocates 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 回答
1

不,这行不通。首先,它不会编译 --foo_tstate成员被定义为 auint8_t但您正试图将 a 存储uint8_t *在其中。如果你通过bar说类似的东西来解决这个问题foo->state = *state,那么它仍然无法工作,因为虽然bar正在传递一个指向mainstate变量的指针,但它所做的只是取消引用它一次并将结果放入一个结构中。

您可以声明foo_t拥有一个uint8_t *成员,&statemaininto传递bar并将其存储在foo_t. 或者(如果您的代码结构允许)完全忘记foo_t,只需将指针传递给statefrom mainto barto zbar。也就是说,其中之一:

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; ... }

[编辑添加:在这种情况下,您还需要声明statevolatile in main,以警告编译器另一个线程可能会修改其值。]

或者

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

另一种说法。“它在线程等中使用。” 做一些奇怪或丑陋的事情并不是一个很好的理由。如果你用线程做的特定事情需要它,当然这是另一回事,当然你没有义务在这里捍卫你的设计决策——我只是想提醒你不要看到“这里是线程”作为做奇怪事情的一般许可。

于 2012-06-07T15:54:29.453 回答