Я думаю, что это выглядит хорошо - так же хорошо, как и всякие ковыряться в неуправляемых землях, в любом случае.
Однако мне интересно, почему начало tokenInformation.ToInt64() + IntPtr.Size
, а не tokenInformation.ToInt64() + 4
(так как тип поля GroupCount - int, а не IntPtr). Это для упаковки / выравнивания структуры или просто что-то подозрительное? Я не знаю здесь.
Использование tokenInformation.ToInt64()
важно, потому что на 64-битной машине взорвется (OverflowException), если значение IntPtr больше, чем то, которое может хранить int. Однако CLR отлично справится с long в обеих архитектурах и не изменит фактическое значение, извлеченное из IntPtr (и, следовательно, вернет его в new IntPtr(...)
).
Представьте себе эту (непроверенную) функцию как вспомогательную оболочку:
// unpacks an array of structures from unmanaged memory
// arr.Length is the number of items to unpack. don't overrun.
void PtrToStructureArray<T>(T[] arr, IntPtr start, int stride) {
long ptr = start.ToInt64();
for (int i = 0; i < arr.Length; i++, ptr += stride) {
arr[i] = (T)Marshal.PtrToStructure(new IntPtr(ptr), typeof(T));
}
}
var attributes = new SID_AND_ATTRIBUTES[groups.GroupCount];
PtrToStructureArray(attributes, new IntPtr(tokenInformation.ToInt64() + IntPtr.Size), sidAndAttrSize);
Удачного кодирования.