首页 > 解决方案 > 使用 Visual Studio 2019 时的负 Array.Length

问题描述

在我的应用程序中,我创建了一个具有预定义大小的数组,然后将其固定并由非托管库填充。只要应用程序是使用 Visual Studio 2017 构建的,这就可以正常工作,但如果应用程序是使用 Visual Studio 2019 构建的,则数组大小不再有意义。数组的长度怎么可能是负数?

//编辑

长的长度是一样的: .

缓冲区是一个完全正常的字节数组

_buffer = new byte[BufferSize];

该方法只是官方 zlib dll 的简单包装。此方法中的错误如何使 .net 混淆数组的大小?

fixed (byte* inputPtr = input)
fixed (byte* bufPtr = _buffer)
{
    _zStreamHandle.ZStream.nextIn = (IntPtr)inputPtr;
    _zStreamHandle.ZStream.availIn = length;
    _zStreamHandle.ZStream.nextOut = (IntPtr)bufPtr;
    _zStreamHandle.ZStream.availOut = BufferSize;
    var dataLeft = false;

    while (_zStreamHandle.ZStream.availIn != 0 || dataLeft)
    {
        var state = _zStreamHandle.Deflate(_flushMode);

        if (state != ErrorCode.Ok)
            throw new VncException("ZStream error: " + state);

        var outCount = BufferSize - (int) _zStreamHandle.ZStream.availOut;
        dataLeft = _zStreamHandle.ZStream.availOut == 0;

        try
        {
            _baseStream.Write(_buffer, 0, outCount);
        }
        catch (Exception e)
        {
            var bufferLength = _buffer.Length;
            var bufferLongLength = _buffer.LongLength;
            Debugger.Break();
        }

        _zStreamHandle.ZStream.nextOut = (IntPtr)bufPtr;
        _zStreamHandle.ZStream.availOut = BufferSize;
    }
}

标签: c#.net.net-4.5visual-studio-2019

解决方案


我相信非托管代码在数组数据本身开始之前就在内存上踩踏。您可以使用托管的不安全代码来模拟这一点。确切的结果很可能取决于 CLR,但在我的机器上,这段代码使 .NET 认为数组的长度为 -1:

using System;

class Test
{
    unsafe static void Main()
    {
        byte[] array = new byte[20];
        Console.WriteLine(array.Length);
        fixed (byte* b = array)
        {
            // On my machine, the length of the array starts
            // 8 bytes before the array data itself
            byte* lengthPtr = b - 8;

            // So let's stop on those four bytes...
            *lengthPtr++ = 255;
            *lengthPtr++ = 255;
            *lengthPtr++ = 255;
            *lengthPtr++ = 255;
        }

        // Prints -1
        Console.WriteLine(array.Length);
    }
}

所以基本上你需要在你的情况下修复非托管库。可能是某个地方存在 32 位/64 位问题 - 我建议您检查所有内容是否都需要相同的架构。


推荐阅读