使用 Visual Studio 2019 时负数 Array.Length
Negative Array.Length while using Visual Studio 2019
在我的应用程序中,我创建了一个具有预定义大小的数组,然后将其固定,并由非托管库填充。只要应用程序是使用 Visual Studio 2017 构建的,这就可以正常工作,但是如果应用程序是使用 Visual Studio 2019 the array size stops making any sense. 构建的,数组的长度怎么可能是负数?
//编辑
long长度相同:
缓冲区是一个完全正常的字节数组
_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;
}
}
我相信非托管代码会在数组数据本身开始之前踩踏内存。您可以使用托管的不安全代码对此进行模拟。确切的结果很可能取决于 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-bit/64-bit 问题 - 我建议您检查所有内容是否都需要相同的架构。
在我的应用程序中,我创建了一个具有预定义大小的数组,然后将其固定,并由非托管库填充。只要应用程序是使用 Visual Studio 2017 构建的,这就可以正常工作,但是如果应用程序是使用 Visual Studio 2019 the array size stops making any sense. 构建的,数组的长度怎么可能是负数?
//编辑
long长度相同:
缓冲区是一个完全正常的字节数组
_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;
}
}
我相信非托管代码会在数组数据本身开始之前踩踏内存。您可以使用托管的不安全代码对此进行模拟。确切的结果很可能取决于 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-bit/64-bit 问题 - 我建议您检查所有内容是否都需要相同的架构。