【问题标题】:Condition is not resolved as expected条件未按预期解决
【发布时间】:2020-08-06 22:24:14
【问题描述】:

我正在使用这个库来获取可用磁盘空间量:

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetDiskFreeSpaceEx(string lpDirectoryName, out ulong lpFreeBytesAvailable, out ulong lpTotalNumberOfBytes, out ulong lpTotalNumberOfFreeBytes);

我在方法中使用它为:

var result = GetDiskFreeSpaceEx(desiredInstallLocation, out var freeBytesAvailable, out var totalNumberOfBytes, out var totalNumberOfFreeBytes);

然后条件来了:

if (gameSize > (int)freeBytesAvailable)
{
    MessageBox.Show($"There is not enough disk space!\nYou need to free at least {ConvertBytesToMegabytes(gameSize - (int)freeBytesAvailable)} MB.", "Not enough space on a disk", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
    return false;
}

调试记录如下:

为什么条件通过了?

【问题讨论】:

  • 尝试转换为更大的类型,即if ((long)gameSize > freeBytesAvailable)

标签: c# wpf .net-core kernel marshalling


【解决方案1】:

问题是您将freeBytesAvailable 转换为int,但它是ulongGetDiskFreeSpaceEx返回的值是377,325,965,312,超过了int的最大值(2,147,483,647)。

因此,ulong 的最少 32 位被用于向下转换的 int,在您的情况下这是一个负数,因为它的最高有效位是 1。因此,条件将是true

11011010011000010101000000000000 (-631156736)

改为将gameSize 转换为ulong,这样您就不会丢失信息。

if ((ulong)gameSize > freeBytesAvailable)

【讨论】:

  • 就是这样。调试器显示的是377325965312 而不是-631156736,这不是很奇怪吗?
  • @Chyuae 不,这并不奇怪。调试器只是显示freeBytesAvailable 的值,而不是(int)freeBytesAvailable。如果你为它创建一个局部变量,你会看到。强制转换变量不会更改 freeBytesAvailable 的值。
猜你喜欢
  • 2019-01-22
  • 1970-01-01
  • 2021-12-13
  • 2015-04-21
  • 1970-01-01
  • 1970-01-01
  • 2018-06-06
  • 1970-01-01
  • 2016-08-26
相关资源
最近更新 更多