在 C 中将 uint_8* 转换为任何类型,例如 "double" 或结构?
Convert uint_8* to any type, say "double" or a struct, in C?
在C语言中,我有一段程序是这样的
void foo(A a);
这里,类型A是已知的。它可以是任何类型,int、指针或结构,或任何用户编写的类型。
现在我有一个指针指向的数据,比如说 uint8_t* data
大小 n
如何将 data
转换为 A 类型的 a
?
我正在使用模糊测试后端从类型 uint8_t*
和大小 n
的随机数据中测试 foo。
假设您从流中读取字节 (uint8_t) 并希望将数据传递给您的函数 foo.
要遵循的步骤:
- 您确定读取了数据类型 A 的序列化信息吗?
- 您确定至少读取了 sizeof(A) 个字节吗?
- 你确定你的类型 A 是(一般)可序列化的吗? (例如,如果 A 包含指向另一个对象的指针怎么办)
然后
foo((A) data); // <- remember: A is just a placeholder, but data is a pointer to uint8_t
Convert uint8_t* to any type in C?
无法用 C 语言进行通用操作。 C语言没有reflection,没有它就谈不上“任何类型”。在不知道“任何类型”对象表示形式并且不知道用于在 uint8_t
对象的指针 to/array 中对该对象进行编码的序列化方法的情况下,通常无法自动猜测转换函数。
您可以解释 uint8_t*
指向的字节集。使用指针别名将导致 strict alias violation and access may not be aligned 并可能最终导致未定义的行为。您也可以使用 memcpy
(这很可能是您实际想要做的):
void foo(A a, size_t arrsize, uint8_t arr[arrsize]) {
assert(arrsize >= sizeof(A)); // do some rudimentary safety checks
memcpy(&a, arr, sizeof(A));
// use a
printf("%lf", a.some_member);
}
或使用 union
进行类型双关,但这可能会导致 trap representation and may cause program to perform a trap,但最终你会没事的。
实际将值数组转换为目标类型的唯一正确方法是实际编写deserialization/conversion函数。该算法将取决于 A
类型的对象表示以及源类型的格式和编码(json?yaml?“原始”(?)字节大端?小端?MSB? LSB? 等..).
请注意,uint8_t
表示一个正好占用 8 个字节的数字,范围为 0 到 255。在 C 中表示“字节”使用 unsigned char
类型。 unsigned char
特别提到对齐要求最小,sizeof
等于1可以alias any object with a char*
pointer.
在C语言中,我有一段程序是这样的
void foo(A a);
这里,类型A是已知的。它可以是任何类型,int、指针或结构,或任何用户编写的类型。
现在我有一个指针指向的数据,比如说 uint8_t* data
大小 n
如何将 data
转换为 A 类型的 a
?
我正在使用模糊测试后端从类型 uint8_t*
和大小 n
的随机数据中测试 foo。
假设您从流中读取字节 (uint8_t) 并希望将数据传递给您的函数 foo.
要遵循的步骤:
- 您确定读取了数据类型 A 的序列化信息吗?
- 您确定至少读取了 sizeof(A) 个字节吗?
- 你确定你的类型 A 是(一般)可序列化的吗? (例如,如果 A 包含指向另一个对象的指针怎么办)
然后
foo((A) data); // <- remember: A is just a placeholder, but data is a pointer to uint8_t
Convert uint8_t* to any type in C?
无法用 C 语言进行通用操作。 C语言没有reflection,没有它就谈不上“任何类型”。在不知道“任何类型”对象表示形式并且不知道用于在 uint8_t
对象的指针 to/array 中对该对象进行编码的序列化方法的情况下,通常无法自动猜测转换函数。
您可以解释 uint8_t*
指向的字节集。使用指针别名将导致 strict alias violation and access may not be aligned 并可能最终导致未定义的行为。您也可以使用 memcpy
(这很可能是您实际想要做的):
void foo(A a, size_t arrsize, uint8_t arr[arrsize]) {
assert(arrsize >= sizeof(A)); // do some rudimentary safety checks
memcpy(&a, arr, sizeof(A));
// use a
printf("%lf", a.some_member);
}
或使用 union
进行类型双关,但这可能会导致 trap representation and may cause program to perform a trap,但最终你会没事的。
实际将值数组转换为目标类型的唯一正确方法是实际编写deserialization/conversion函数。该算法将取决于 A
类型的对象表示以及源类型的格式和编码(json?yaml?“原始”(?)字节大端?小端?MSB? LSB? 等..).
请注意,uint8_t
表示一个正好占用 8 个字节的数字,范围为 0 到 255。在 C 中表示“字节”使用 unsigned char
类型。 unsigned char
特别提到对齐要求最小,sizeof
等于1可以alias any object with a char*
pointer.