2011-04-17 145 views
0

我聲明瞭一個名爲「Struct」的新結構體 我有一個通用函數,它接受一個參數「void * data」。將一個結構體傳遞給一個通用函數C

void Foo(void *data) 

我通過「結構」的一個實例爲通用功能。

Struct s; 
Foo(&s); 

我想訪問函數中結構的屬性之一。

void Foo(void *data) { 
    char *word = (char*) data.word; 
} 

這是不允許的,因爲它不會將數據識別爲有效的結構。

我甚至嘗試首先聲明數據爲結構類型,並且出現錯誤。

void Foo(void *data) { 
    Struct s = (Struct) data; 
    char *word = s.word; 
} 

我得到「轉化爲要求的非標型」。

+1

如果你需要它是一個Struct,爲什麼要在第一個地方傳遞void *? – 2011-04-17 20:48:26

+1

@Bo:該函數可能是一個回調函數,必須符合外部指定的API,調用者和函數會知道'void * data'應該是什麼,但是它們之間的代碼可能不會。查看'bsearch'和'qsort'作爲標準庫的例子。 – 2011-04-17 21:00:22

回答

3

第一所有的,你應該打開你的編譯器的警告標誌(所有這些)。然後,你應該通過一個指針,你Struct,並使用比struct其他東西作爲變量名:

Struct s; 
Foo(&s); 

然後,在Foo

void Foo(void *data) { 
    Struct *s = data; 
    char *word = s->word; 
} 

你不能非指針類型轉換成和從void*就像你正在嘗試,指針類型轉換和從void*另一方面,是有效的。

+0

+ 1用於觀察'struct'是C. – 2011-04-17 20:47:45

+0

中的一個關鍵字嗎?這有點太...例如,在gcc中,選項'-Wwrite-strings'使得gcc成爲類似於C語言的編譯器,但不是'C':) – pmg 2011-04-17 20:55:24

+1

@pmg:所有這些(和' - 也就是錯誤!),直到你能清楚地解釋哪些可以被丟棄,爲什麼:)當你從Grasshopper手中抓取這個警告開關時,你就會準備好。 – 2011-04-17 20:58:25

1

當通過指針請求結構成員時,必須使用->運算符。

這應該工作:char *word = (char*) data->word;

你還必須結構的地址傳遞給函數。像這樣:Foo(&struct);

0

數據是指針,所以無論你將它轉換爲必須也是一個指針。如果你說Struct* myStruct = (Struct*) data,一切都會和世界一致。

0

你在混合指針和數據。

Struct struct定義數據對象
void *data預計data是一個指針。

呼叫Foo有一個指向Struct,並進行其他必要的更改

2

您需要將指針傳遞給您結構和獲得一個指向函數內部的結構:

Struct struct; 
Foo(&struct); 

void Foo(void *data) { 
    Struct* struct = (Struct*) data; 
    char *word = struct->word; 
} 
+0

另外,使用'struct Struct struct'。 – 2011-04-17 20:47:00

+2

轉換爲'(Struct *)'是不必要的。有些人喜歡將其包含在內,但我相信最好不要這樣做,因爲如果您嘗試將非空指針指派給本地變量,它會阻止編譯器警告您。 – psmears 2011-04-17 20:47:37

+2

哦,還有:'struct'是一個保留字 - 爲本地變量選擇另一個名稱。 @Radek:如果'Struct'是typedef的名字,則不行。 – psmears 2011-04-17 20:48:17

0
Struct struct; 
Foo((void*)&struct); 

void Foo(void *data) { 
    Struct *struct = (Struct*)data; 
    char *word = struct->word; 
} 

或更緊湊的形式:

Struct struct; 
Foo((void*)&struct); 

void Foo(void *data) { 
    char *word = ((Struct*)data)->word;   
} 
1

首先,你需要正確地調用該函數:

Struct s; 
Foo(&s); 

通知你現在指針傳遞到結構。現在

,該功能必須知道你正在使用一個Struct(而不是別的東西) - 可能是因爲其它的參數,或者一個全局變量,或者一些其他原因。然後在你可以做的功能裏面:

void Foo(void *data) { 
    Struct *structpointer = p; /* Note - no need for a cast here */ 


    /* (determine whether data does refer to a pointer then...) */ 
    char *word = structpointer->word; 
    /* ... then use 'word'... */ 
} 
相關問題