【发布时间】:2019-09-29 11:26:18
【问题描述】:
我需要使用 kernel32 的 SetFilePointer 函数来读取磁盘的一个扇区,该扇区的地址包含在 double 中,以解决大小问题。 我知道 ReadFile 函数接受 loword as long 和 hiword 作为 long 参数,但我无法将我的双地址拆分为两个字。
我尝试了几种使用Mod和Fix的方法,但最后我只有溢出错误。
LoWord = CLng(dNum Mod CDbl(4294967295)) 'Dont care the number I use, I always get overflow error
或
LoWord = CLng(FMod(dNum, 4294967295#))
HiWord = CLng(dNum - (FMod(dNum, 4294967295#))) 'tryed different number to see the behaviour, don't care
在哪里
Public Function FMod(a As Double, b As Double) As Double
FMod = a - Fix(a / b) * b
'http://en.wikipedia.org/wiki/Machine_epsilon
'Unfortunately, this function can only be accurate when `a / b` is outside [-2.22E-16,+2.22E-16]
'Without this correction, FMod(.66, .06) = 5.55111512312578E-17 when it should be 0
If FMod >= -2 ^ -52 And FMod <= 2 ^ -52 Then '+/- 2.22E-16
FMod = 0
End If
End Function
我尝试将双精度转换为 byteArray 或十六进制字符串以尝试“手动”字节移位,但没有成功。
我已经看到了Convert Double into 8-bytes array,但是没有修改的示例总是将 dNum=1 转换为 [0, 0, 0, 0, 0, 0, 240, 63] 的结果,它似乎不是正确的.
你有什么技巧或其他方法可以在 VB6 中从磁盘读取具有大地址的扇区吗?
感谢大家阅读我的问题。
为了更好地说明我在做什么: 我知道也许 vb6 不是最好的选择,但现在我已经开始了...... 我从一个十六进制格式(作为字符串)的 INI 文件(可变)中读取了一个扇区号,我将其转换为 Long(但它应该以双精度传送还是什么?),考虑到每个扇区 512 个字节。 从那个扇区开始,我必须从磁盘读取的字节数是一个常数。
当我使用该功能时
Call SetFilePointer(hDevice, iStartSec * BytesPerSector, 0, FILE_BEGIN)
我必须指定字节数,然后我必须乘以 512。这导致了我试图绕过的溢出。
我也试过这个方法:
Private Type TKK_Dbl
Value As Double
End Type
Private Type Dbl2Long
LowVal As Long
HighVal As Long
End Type
Private D As TKK_Dbl
Private L As Dbl2Long
在函数中...
D.Value = CDbl(iStartSec) * CDbl(BytesPerSector)
LSet L = D
Call SetFilePointer(hDevice, L.LowVal, L.HighVal, FILE_BEGIN)
但它对我不起作用。
【问题讨论】:
-
你永远不想存储指针in a
double。 -
VB6 没有
LongLong数据类型,因此没有可拆分的来自。Double虽然也占用 8 个字节,但其内部结构与整数完全不同,因此您不能只复制字节。有Decimal,但它也有错误的大小。使用SetFilePointer时,您通常开始 使用两个Longs 作为地址。如果它是一个预定义的常量,则将其声明为两个Longs 开头。如果从文件中读取,则将其读取为两个Longs。 -
实际上,VB6 Currency 数据类型实际上是一个 8 字节整数类型。小数点只是隐含的。如果您正确设置了声明,则在使用 API 时可以忽略它。但是 GSerg 绝对正确,您不应该尝试将任何类型的指针存储在 double 中。
-
感谢您指出我不要使用 Double,也许是货币。我可以尝试在乘以 512 之前将扇区号一分为二,但我必须研究如何管理拆分结果以具有与从 INI 读取的扇区号相对应的正确字节数。我在问题的末尾添加了更多详细信息。
标签: vb6