繁体   English   中英

是否可以确定IntPtr是指向32位浮点还是指向64位浮点数?

[英]Is it possible to determine if an IntPtr is pointing to a 32-bit or to a 64-bit float?

如果在.NET(C#)中接收到任意IntPtr ,是否可以确定它指向的是32位还是64位浮点型并将其安全地转换为.NET float型? 还是需要明确的类型知识?

IntPtr 绝不float IntPtr是一个指针 永远不要将IntPtr用作值-它仅用于指针。 我已经看到了很多使用IntPtr进行值互操作的尝试,但这总是一个糟糕的主意。

这种暗示意味着与非托管环境进行互操作-这样做通常意味着失去几乎所有类型的安全-剩下的就是您的纪律。 没有元数据可以通过,您必须了解所有内容的正确类型。 为什么需要所有这些头文件是有原因的-缺少逆向工程,没有办法知道什么是函数参数(甚至调用约定)。

即使为您提供了一个真实的指针(而不仅仅是一个被掩码的值),您也无法知道给您的内容的数据类型-它不在非托管互操作合同中的任何地方。

即使您确实在处理一个只能是floatdouble float的指针,也无法知道要传递多少字节-信息根本就不存在。 只是一个数字-内存指针。 没有类型信息,甚至没有长度信息。

在这样的时代,您真的很欣赏.NET互操作多么简单-所有这些问题都在后台得到解决。

不,没有办法神奇地确定指针指向的内容-当您收到IntPtr ,得到的只是内存地址-在从该地址读取数据之前需要知道要读取多少字节以及如何处理这些字节。

如果指针可能指向不同大小的数据,则您将需要额外的信息来描述指针所指向的数据。

在最一般的情况下,不可能。 八字节(双精度)值的前四个字节在解释时就好像它们是单精度值一样,有些含义。

但是,如果您有一些其他知识(例如,值始终落在某个范围内/始终是有限的),则可以区分“四个字节是单个精度值”和“四个字节是对一个字节的部分读取”双精度值”。 要真正将其转化为检测算法,需要很多运气(关于您希望接收的数据的限制)。

在某些情况下,您可以从指针对齐方式推断出大小。 四字节对齐绝对不是双精度值。 八字节对齐可以是任意精度,因此这是不可靠的。 但是,这可能有助于您避免读取超出页面边缘的多余字节并导致访问冲突。

如果您想沿着这条路走下去(请注意,对于某些数据,您可能无法确定,并且维护工作将变得不那么有趣),则可以使用Marshal.Copy将数据抓取到字节数组中,然后BitConverter以及BitConverter进行位测试,以将它们解释为不同精度的浮点值。 请务必熟悉IEEE浮点数编码,指数的有偏编码等。

在另一种极端情况下,如果要传递数据数组,并且仅给出字节长度,而没有给出元素数/每个元素的大小,则很有可能识别重复模式并推断出精度。

总结:这不是构建用于部署的软件的好方法。 但是,如果您正在编写用于处理特定数据集的一次性代码,并且这些代码永远不会落到您的手中,那么您就有可能成功。

如果不了解它所指向的值,就无法确定类型。 最好的办法是检查前32位,以确定它是否是32位浮点格式中实际使用的位模式。 有一些未使用的位模式,因此,如果您发现其中之一,则必须知道它必须是64位数字,否则您仍然不知道。

如果您知道有关数据可以具有的数字范围的信息,则实际上可以确定格式。 例如,如果您知道该指数限制为几个值,则可以确定它是具有8位指数(32位数字)还是具有11位指数(64位数字)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM