2014-06-12 47 views
1

我處於這樣一種情況,我直到運行時才知道結構成員的類型。讀取文件並且該文件包含關於結構成員的數據類型的信息(它將在稍後被初始化)。在運行時永久鑄造空指針

我想知道是否有辦法在運行時永久性地將一個空指針轉換爲另一種類型。我在想這個類型可以用另一種方式表示(比如存儲一個包含類型的字符串)。但是這會引入很多開銷來正確訪問void *(每個潛在類型的if語句)。

任何想法或更多信息?

謝謝。

+0

你是什麼意思的「永久」? – cmaster

+0

#define SOMETHING_I_WILL_KNOW_LATER void *; SOMETHING_I_WILL_KNOW_LATER myStruct;當你有這些信息時,你#undef SOMETHING_I_WILL_KNOW_LATER並用正確的值重新定義它。 – Yann

+1

顯示你的代碼,我們可能正確地理解你希望達到的目標(因爲你的問題不是很清楚),以及是否有可能。 –

回答

2

讓我們考慮您的文件的格式如下

offset 1: count of elements 
offset 2: size of the 1st element 
offset 2+1: size of 2nd element 
... 
offset 2+count-1: size of the last element 

offset 2+count: content of 1st element 
offset 2+count+size of 1st elem: content of 2nd element 
... 

,並認爲你有一個文件有3個要素:

1st elem: 
    size = 2 bytes 
    content = 0x3412 
2nd elem: 
    size = 1 byte 
    content = 0xAB 
3rd elem: 
    size = 5 bytes 
    content = "Hell" (null terminated) 

下面有一個C程序,它創建這樣的文件然後解釋它。功能readFile將與任何文件有關的先前描述的格式。

警告:這只是一個可以做什麼的例子。請注意,分配的內存不會被釋放,也不會檢查I/O操作!

#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 
struct Elem{ 
    int size; 
    void *content; 
}; 

struct List{ 
    int count; 
    struct Elem *elems; 
}; 

struct List *list; 

void createFile(char *name) 
{ 
    FILE *f; 
    char buf[50]; 
    buf[0] = 3; /* nb elems */ 
    buf[1] = 2; /* size of elem 1 */ 
    buf[2] = 1; /* size of elem 2 */ 
    buf[3] = 5; /* size of elem 3 */ 
    /* elem 1 */ 
    buf[4] = 0x12; 
    buf[5] = 0x34; 
    /* elem 2 */ 
    buf[6] = 0xab; 
    /* elem 3 */ 
    buf[7] = 'H'; 
    buf[8] = 'e'; 
    buf[9] = 'l'; 
    buf[10] = 'l'; 
    buf[11] = '\0'; 
    f = fopen(name, "wb"); 
    fwrite(buf, 12, 1, f); 
    fclose(f); 
} 

void readFile(char *name) 
{ 
    FILE *f; 
    char c; 
    int i; 
    f = fopen(name, "rb"); 
    /* read number of elements */ 
    fread(&c, 1, 1, f); 
    list->count = c; 
    list->elems = (struct Elem*)malloc(sizeof(struct Elem) * c); /* allocate the needed size */ 
    for(i = 0; i < list->count; i++) 
    { 
     /* read the size of current element's size */ 
     fread(&c, 1, 1, f); 
     list->elems[i].size = c; 
     list->elems[i].content = malloc(c); /* allocate the needed size */ 
    } 
    for(i = 0; i < list->count; i++) 
    { 
     /* read the current element's content */ 
     fread(list->elems[i].content, list->elems[i].size, 1, f); 
    } 
    fclose(f); 
} 

int main(int argc, char **argv) 
{ 
    createFile("test"); 
    list = (struct List *)malloc(sizeof(struct List)); 
    readFile("test"); 
    printf("elem 1: %04X\n", *((unsigned short*)list->elems[0].content)); 
    printf("elem 2: %02X\n", *((unsigned char*)list->elems[1].content)); 
    printf("elem 3: %s\n\n", (char*)list->elems[2].content); 
    /* you should free the allocated memory */ 
    return 0; 
}  

輸出的結果是:

elem 1: 3412 
elem 2: AB 
elem 3: Hell 

還有就是結構的填充方式:

list -> count = 3 
     elems[0]-> size = 2 
        content = 0x3412 
     elems[1]-> size = 1 
        content = 0xAB 
     elems[2]-> size = 5 
        content = {'H', 'e', 'l', 'l', 0} 

注:

您可能已經注意到,該元素鑄造到unsigned short保存爲序列{0x12, 0x34},具有16位值0x3421。這是由於我的計算機的小端存儲體系結構在較低地址存儲較低有效字節(see)。

+0

+1,但你也許應該說一些關於排序的東西。 – zwol

+0

@Zack當然!我不想談論脫離主題的東西,但我會在你問的時候加一句話。 – daouzli

0

這在C中是不可能的,因爲在編譯時你不知道在運行時永久性轉換應該是什麼。

(用C++,你可以做靜態或動態的多態性的東西)

+0

我會說沒什麼*不可能*在C :) – daouzli