【问题标题】:Dynamic data type casting in C++C++ 中的动态数据类型转换
【发布时间】:2015-09-04 14:38:50
【问题描述】:

我正在开发一个 DLL,它使用一组固定的 10 种数据类型:8/16/32/64 位的无符号/有符号整数和 32/64 位的浮点数。

我从客户端收到一个指向缓冲区的 void 指针以及一个表示数据类型的枚举。然后我必须查看提供的数据类型枚举,以了解要将缓冲区转换为哪种数据类型以提取值。

例子:

nU8Val  = (*(U8*)pvBuffer);
nU16Val = (*(U16*)pvBuffer);
nU32Val = (*(U32*)pvBuffer);

有没有办法把这个逻辑组合成一行,比如:

nMyVal = *((TypeOf(nMyVal)*)pvBuffer);

我不需要为所有数据类型定义变量并为每个数据类型枚举重复相同的逻辑

编辑:我更新了示例逻辑,以便清楚地了解我试图做的事情,将 void* 缓冲区转换为接收变量数据类型的指针

【问题讨论】:

  • 你不能动态做,但你可以使用一些模板代码。但是要给出答案/建议,缺少一块:您想对结果做什么?
  • 我需要将结果与定义的限值进行比较。我有一个具有 MAX 和 MIN 值的数据点,我通过 void* 接收到该点的一条新数据,需要根据数据类型提取它并确保它在 MIN 和 MAX 的范围内跨度>
  • 给你的.dll添加一个C++接口自然可以解决问题。
  • 好的,我会为此阅读一些文档。感谢您的快速回复。
  • 不,你不能。我能想到的唯一方法是让一个类处理转换,并将不同类型的值存储为双精度值。这意味着您会将输入的每个值 n 转换为双精度值,而不是最佳解决方案。

标签: c++ casting void-pointers


【解决方案1】:

这里有一个模板,可以从受让人推导出类型,这样就不用重复了:

template<typename To>
void copy_deduced(void* from, To& to) {
    to = *reinterpret_cast<To*>(from); // avoid c-style casts
}
copy_deduced(pvBuffer, nU8Val);
// ...

【讨论】:

  • memcpy(&amp;to, from, sizeof to); 将达到相同的效果,但不会违反严格的别名规则
  • 模板解决了我的问题。我能够使用数据类型的模板创建一个比较函数,然后将传递给函数的 void 指针缓冲区转换为我需要的任何类型。再次感谢。
【解决方案2】:

这里的问题是它已经是动态类型,即void*。如果我正确理解您的问题,我会做的是创建一个带有 void* 的结构(我将分配一个新块)和一个表示数据类型的枚举值。然后,在使用这些值时,使用 switch 语句在非常相似的代码段中做出决定。您不能像 cmets 中建议的那样简单地将所有内容转换为某种 64 位类型,例如 double 或 unsigned long long,因为如果分配小于 8 个字节,这可能会导致未经授权的成员 l 内存访问错误,即完全可以想象,因为 70% 的可能类型都比这小。

【讨论】:

  • 我不确定是否有人建议将所有内容转换为 64 位类型。我目前使用的逻辑已经是一个 switch 语句,它根据数据类型枚举值转换数据。我的问题是看看是否有办法将 void* 缓冲区中的数据动态转换为接收转换结果的变量的数据类型
  • 在这种情况下,显而易见的解决方案是模板,如上一个答案中所建议的那样。但是,如果你不想使用模板,例如,如果你想公开一个 C api,或者你想限制你的类型白名单,你要么会被我建议的东西卡住,要么只是原始空指针。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-17
  • 1970-01-01
相关资源
最近更新 更多