Арифметическая операция привела к переполнению C#
Я получаю следующую ошибку при разблокировке файла
Арифметическая операция привела к переполнению
System.IntPtr.ToInt32
Я подозреваю, что это следующая строка pBuffer.ToInt32()
:
IntPtr iPtr = new IntPtr(pBuffer.ToInt32() + (i * Marshal.SizeOf(fi3)));
Я не могу воспроизвести ошибку самостоятельно, и ошибка не отображает правильный номер строки. Я ищу способ воспроизвести эту или любую обратную связь о возможной причине. Спасибо
public void Close()
{
const int MAX_PREFERRED_LENGTH = -1;
int readEntries;
int totalEntries;
IntPtr pBuffer = IntPtr.Zero;
FILE_INFO_3 fi3 = new FILE_INFO_3();
int iStatus = NetFileEnum(this.HostName, this.HostPathToShare + this.FileNameFromShare, null, 3, ref pBuffer, MAX_PREFERRED_LENGTH, out readEntries, out totalEntries, pBuffer);
if (iStatus == 0)
{
for (int i = 0; i < readEntries; i++)
{
IntPtr iPtr = new IntPtr(pBuffer.ToInt32() + (i * Marshal.SizeOf(fi3)));
fi3 = (FILE_INFO_3)Marshal.PtrToStructure(iPtr, typeof(FILE_INFO_3));
NetFileClose(this.HostName, fi3.fi3_id);
}
}
NetApiBufferFree(pBuffer);
}
[DllImport("netapi32.dll", SetLastError=true, CharSet = CharSet.Unicode)]
static extern int NetFileClose(
string servername,
int id);
[DllImport("Netapi32.dll", SetLastError=true)]
static extern int NetApiBufferFree(IntPtr Buffer);
[DllImport("netapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
static extern int NetFileEnum(
string servername,
string basepath,
string username,
int level,
ref IntPtr bufptr,
int prefmaxlen,
out int entriesread,
out int totalentries,
IntPtr resume_handle
);
Обновить
Я добавил Win32 API-код.
Приведенные ниже ответы выглядят правильно и машина 64-битная. Но я не могу воспроизвести его на сервере dev, несмотря на то, что среда разработки 64-битная. Есть идеи по воспроизведению ошибки?
2 ответа
Ошибка вызвана тем, что ваш код работает в 64-битном контексте и возвращает адрес указателя, который находится за пределами диапазона, адресуемого 32-битным, поэтому .ToInt32()
броски.
Вызовите Environment.Is64BitProcess, чтобы определить, работает ли ваш процесс в 32- или 64-разрядном режиме, и соответствующим образом преобразовать адрес:
long pointerAddress;
if (Environment.Is64BitProcess)
{
pointerAddress = pBuffer.ToInt64();
}
else
{
pointerAddress = pBuffer.ToInt32();
}
var fileInfoPointer = new IntPtr(pointerAddress + (i * Marshal.SizeOf(fi3)));
Я сразу вижу две ошибки в коде:
Вы установили свой
pBuffer
до 0, и никогда не выделять его. Должно появиться сообщение об ошибке при передачеNetFileEnum
, хотя это функция Win32 API, поэтому она может не заметить.Вы конвертируете pBuffer
.ToInt32()
, который должен работать, когда он специально скомпилирован для x86, но если в качестве целевой платформы у вас есть Any CPU или x64, это тоже будет проблемой.