检查正确的类型转换

时间:2009-12-14 05:16:07

标签: c casting

是否有一种比通用指针强制转换数据的更安全的方法。 更具体地说,有没有办法检查类型转换是否安全。

假设我们从netwrking代码中的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可以是struct data1或struct data2。 以下是我的问题:

  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
    

3 个答案:

答案 0 :(得分: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原始数据并不安全或建议。即使您使用相同类型的体系结构,结构填充等,也可能因不同的可执行文件,编译器等而有所不同。如果您使用的是不同的计算机,则可能需要处理字节序问题。

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

答案 1 :(得分:2)

如果你已经序列化了数据并发送了它,那么现在你所拥有的只是原始字节。无法确定原始数据的类型。

尝试和缓解问题的唯一方法是创建一种标准的方式来传达类型。简单的方法:

enum possible_types
{
    t_data1 = 0,
    t_data2,
};

首先发送。接收器可以检查它在那里的类型。

答案 2 :(得分:0)

结帐Serialization—How to Pack DataSon of Data Encapsulation

当我们传输结构时,我们必须注意字节顺序和类型大小 简单的类型转换总是不够。