通过IntPtr循环构建struct数组出错
本文关键字:数组 出错 struct 构建 IntPtr 循环 通过 | 更新日期: 2023-09-27 18:07:32
我在另一个struct
中从IntPtr
构建struct
s数组时遇到了问题。
这个结构是由我使用的Windows API返回的:
public struct DFS_INFO_9 {
[MarshalAs(UnmanagedType.LPWStr)]
public string EntryPath;
[MarshalAs(UnmanagedType.LPWStr)]
public string Comment;
public DFS_VOLUME_STATE State;
public UInt32 Timeout;
public Guid Guid;
public UInt32 PropertyFlags;
public UInt32 MetadataSize;
public UInt32 SdLengthReserved;
public IntPtr pSecurityDescriptor;
public UInt32 NumberOfStorages;
public IntPtr Storage;
}
[DllImport("netapi32", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int NetDfsEnum([MarshalAs(UnmanagedType.LPWStr)]string DfsName, int Level, int PrefMaxLen, out IntPtr Buffer, [MarshalAs(UnmanagedType.I4)]out int EntriesRead, [MarshalAs(UnmanagedType.I4)]ref int ResumeHandle);
我正试图获得IntPtr Storage
引用的DFS_STORAGE_INFO_1
s数组。
结构是这样的(如果重要的话):
public struct DFS_STORAGE_INFO_1 {
public DFS_STORAGE_STATE State;
[MarshalAs(UnmanagedType.LPWStr)]
public string ServerName;
[MarshalAs(UnmanagedType.LPWStr)]
public string ShareName;
public IntPtr TargetPriority;
}
到目前为止,这段代码一直在努力获得只有一个存储的DFS_INFO_9
,但是当试图封送数组中的第二个项时失败了。
DFS_INFO_9 info = GetInfoFromWinApi();
List<DFS_STORAGE_INFO_1> Storages = new List<DFS_STORAGE_INFO_1>();
for (int i = 0; i < info.NumberOfStorages; i++) {
IntPtr pStorage = new IntPtr(info.Storage.ToInt64() + i * Marshal.SizeOf(typeof(DFS_STORAGE_INFO_1)));
DFS_STORAGE_INFO_1 storage = (DFS_STORAGE_INFO_1)Marshal.PtrToStructure(pStorage, typeof(DFS_STORAGE_INFO_1));
Storages.Add(storage);
}
我得到一个FatalExecutionEngineError
,吐出错误代码0x0000005(访问被拒绝)。我假设DFS_STORAGE_INFO_1
的大小被错误地计算,导致marshal试图访问为数组分配的内存之外的内存。但这发生在i = 1
上,当时可能有7个存储需要通过。也许是我的想法有问题,但我不知道如何改正。
DFS_STORAGE_INFO_1
的实际定义是:
public struct DFS_STORAGE_INFO_1 {
public DFS_STORAGE_STATE State;
[MarshalAs(UnmanagedType.LPWStr)]
public string ServerName;
[MarshalAs(UnmanagedType.LPWStr)]
public string ShareName;
DFS_TARGET_PRIORITY TargetPriority;
}
TargetPriority是一个结构,定义如下:
public struct DFS_TARGET_PRIORITY {
public DFS_TARGET_PRIORITY_CLASS TargetPriorityClass;
public UInt16 TargetPriorityRank;
public UInt16 Reserved;
}
public enum DFS_TARGET_PRIORITY_CLASS {
DfsInvalidPriorityClass = -1,
DfsSiteCostNormalPriorityClass = 0,
DfsGlobalHighPriorityClass = 1,
DfsSiteCostHighPriorityClass = 2,
DfsSiteCostLowPriorityClass = 3,
DfsGlobalLowPriorityClass = 4
}
对于FatalExecutionEngineError
,我认为DFS_STORAGE_INFO_1
的大小被错误地计算了,因为它被错误地定义了。当试图将指针转换为它们引用的结构时,下一个索引是错误的,因为大小关闭了。当转换内存块时,它可能引用了一个不应该被访问的块,抛出"Access Denied (0x0000005)"错误。