是否有一种比通用指针强制转换数据的更安全的方法。 更具体地说,有没有办法检查类型转换是否安全。
假设我们从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。 以下是我的问题:
我们可以对buf中存储的类型进行某种检查吗?
如果发生以下情况会发生什么:
// buf contains a message of type data1
struct data2 *d2; // assume its malloced too
d2 = (struct data2)buf;
d2->val3=3.145
答案 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 Data和Son of Data Encapsulation。
当我们传输结构时,我们必须注意字节顺序和类型大小 简单的类型转换总是不够。