2012-06-07 61 views
-2

我真的不知道如何給這個問題一個很好的標題 - 對不起。指針魔術:結構與指針成員和更多

就知道什麼是這一切的目標是:通過一個uint8_t變量的指針吧(),它不會將其設置爲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結構,根本不是問題。

請不要擔心我爲什麼這麼奇怪,它的線程等

+0

您的問題,因爲它是目前編寫是沒有意義的。你寫的內容沒有問題,你希望我們做什麼? –

+0

我想通過指向我通過bar()zbar,然後確實變量的值與地址狀態爲1或0,我可以讀出我的主狀態。 我想所有的問題是:我如何訪問一個變量的值,這是一個指針成員在一個結構中,我得到的結構>指針< –

回答

2

我假設你的意思是void bar(uint8_t* state)

它不會做我認爲你的意圖。我再次假設您想要更改main中的state變量?如果是這樣嘗試

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

tihnk這是你想要做什麼

+0

aaah!這很有幫助,謝謝你的幫助:) 是的,這是我想要做的:D –

2

bar()需求中使用通過指針把它的參數。另外,如果你想檢查main的狀態,你將需要調用zBar

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

您正確稱其爲mainbar(&state);

注意,以後的路所指向的改變bool它現在這個代碼,一旦調用zbarstate將永不再改變。如果你想有一個線程訪問(和修改)的狀態,你需要將地址存儲在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

+0

我編輯了我的第一個帖子,這是我的壞。這是一個錯字。 –

+0

@Tectu - 查看我的更新 – Attila

+0

謝謝,這有助於。 現在一切正常,因爲感到:) –

1

不,這是行不通的。首先,它不會編譯 - foo_tstate成員被定義爲uint8_t,但您試圖在其中存儲uint8_t *。如果通過使bar說明類似於foo->state = *state來解決此問題,那麼它仍然不起作用,因爲雖然bar正在傳遞一個指向mainstate變量的指針,但它所做的只是將其解除引用一次,並將結果置於結構。

你可以聲明foo_tuint8_t *成員,從main通過&statebar,並存儲在foo_t。或者(如果您的代碼結構允許)忘記foo_t,並將指針從main指向statebarzbar。也就是說,其中的一個:

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震盪main,以警告其他線程可能會修改其值爲編譯]

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

另外一句話。 「它用在線程等內部」對於做一些奇怪或醜陋的事情並不是一個很好的理由。如果有一個具體的原因爲什麼你要用線程做的事情需要它,當然這是另一回事,當然你沒有義務在這裏捍衛你的設計決定 - 我只是要小心你反對看到「這裏是線程」作爲一般許可證做奇怪的事情。

+0

我改變了我的第一篇文章中的酒吧事情,這是一個錯字,它需要一個uint8_t *。 它需要一個結構,因爲那裏還有其他成員。 但是我怎樣才能訪問實際狀態的值,我有我的結構中的指針? –

+0

在發佈的代碼中,結構中沒有指針,結構中有一個實際的'uint8_t'值。我提到的兩個選項中的第一個在結構中放置了一個指針,並且 - 如果我已經正確理解了你 - 實現了你要求的完全一致...除了我意識到我沒有展示什麼代碼'main'然後需要做。我會編輯我的答案,使其更清晰。 –

+0

實際上,不,main'中的代碼看起來和現在一樣。除非'state'可能在另一個線程中被更改,否則最好在'main':'volatile uint8_t state;'中聲明它爲'volatile'。 –

2

認爲你的意思是:

  • 線程1個運行main和有一個局部變量uint8_t state
    • 它會檢查這個局部變量的值環路,期待它可以異步通過zbar
  • 線程zbar
    • zbar改變的arg->state的價值,你想main看到線程的新值更新2個運行(除其他事項外)1

所以,首先,你需要確保arg->statemain S」本地state變量實際上是指內存中的相同位置。由於bar已經分配foo_t arg,它可能更容易作出這樣的共享副本:

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

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

其次,你需要在該位置,以確保main實際上看到新的價值:爲INFACT說,有幾件事可能會阻止這一點。最明顯的是,沒有要求main有史以來在第一次調用bar後重新加載state的值,因爲它看不到任何可能改變它的東西。

這東西本質上是不可移植的;告訴我們該平臺,我們將能夠提供更多信息。