2009-12-14 55 views
1

有没有一种更安全的方式来从泛型指针中对数据进行类型转换? 更具体地说,是否有方法来检查类型转换是否安全。检查正确的类型转换

假设我们从网络代码中的recv函数接收到void *数据。

假设有两种结构:

struct data1 
{ 
int val; 
double val1; 
} 

struct data2 
{ 
char str[100]; 
long double val3; 
} 

假设我们有以下收到电话:

recv(int s, void *buf, size_t len, int flags); 

与Buf的类型可以是结构数据1或结构数据2的。 这里是我的问题:

  1. 我们可以执行某种检查其中的类型存储在BUF?

  2. 如果出现以下情况,会发生什么:

    // buf contains a message of type data1 
    
    
    struct data2 *d2; // assume its malloced too 
    
    d2 = (struct data2)buf; 
    
    d2->val3=3.145 
    

回答

2

如果你序列化数据并发送它,你现在所得到的是原始字节。没有办法确定什么类型的原始数据。

尝试和缓解问题的唯一方法是创建一种标准的沟通方式。简单的方法:

enum possible_types 
{ 
    t_data1 = 0, 
    t_data2, 
}; 

然后发送。接收者可以检查它假设在那里的类型。

+1

由于t_data1和t_data2具有相同的值(零),我不知道如何区分它们...:D – 2009-12-14 05:31:31

+0

哎呀,呵呵。固定。 :P – GManNickG 2009-12-14 05:43:29

3

我相信你可以做这样的事情(未经测试):

#include <stdio.h> 

struct a { 
    int ival; 
    double dval; 
}; 

struct b { 
    char cval[20]; 
    long double ldval; 
}; 

enum stype_ { 
    TYPE_A, 
    TYPE_B 
}; 

struct combined { 
    enum stype_ stype; 
    union { 
     struct a adata; 
     struct b bdata; 
    } u; 
} 

void f(void *data) 
{ 
    struct combined *c = data; 
    if (c->stype == TYPE_A) { 
     struct a aa = c->u.adata; 
    } else if (c->stype == TYPE_B) { 
     struct b bb = c->u.bdata; 
    } else { 
     fprintf(stderr, "Invalid struct!\n"); 
    } 
} 

int main(void) 
{ 
    struct a a1 = { 0, 0 }; 
    struct b b1 = { "Hi", 0 }; 
    struct combined c; 

    c.stype = TYPE_A; 
    c.u.adata = a1; 
    f(&c); 

    c.stype = TYPE_B; 
    c.u.bdata = b2; 
    f(&c); 

    return 0; 
} 

正如你所看到的,你必须要小心,如果你使用此方案的stype成员设置为正确的值。

小心通过网络发送这样的数据!一般而言,通过网络发送struct是不安全的或不建议的。即使你使用的是相同的体系结构,结构填充等,也可能与不同的可执行文件,编译器等不同。如果你在不同的机器上,你可能不得不处理字节序问题。

将数据序列化到您确切知道其内容的字节然后在接收端解码它们要好得多。如果您确实使用这种方案(强烈推荐),则可以在发送的第一个字节中对信息类型进行编码。

相关问题