【问题标题】:Error looping through IntPtr to build array of struct错误循环通过 IntPtr 构建结构数组
【发布时间】:2013-04-05 19:29:16
【问题描述】:

我在从另一个IntPtr 到另一个struct 中构建structs 数组时遇到问题。

此结构由我正在使用的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_1s 数组。

这是结构(如果重要的话):

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_9s 只有一个存储,但在尝试编组数组中的第二项时失败。

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 的大小被错误计算,导致元帅尝试访问为数组分配的内存之外的内存。但这发生在i = 1 上,当时可能有 7 个存储需要通过。可能是我的想法有问题,但我不知道如何改正。

【问题讨论】:

  • 看这里一​​些珍贵的SO 发布stackoverflow.com/questions/4550207/… 也对这个error code 0xc0000005 (Access Denied)进行谷歌搜索
  • 我见过这样的东西,你可以打赌我用谷歌搜索过。第一个所以帖子建议我试图摆脱的解决方案,运行可执行文件。我正在尝试使用 Windows API 来更好地管理代码,而不必打开命令提示符并希望一切顺利。第二个帖子对我来说毫无意义。
  • 我想我知道你想要什么我看过之前的帖子让我再找一遍看看是否相关
  • TargetPriority 错误。它是一个结构,而不是一个指针。
  • 哇,不敢相信我忽略了这一点。谢谢@HansPassant。你能把它列为答案吗?这是确认它的结构定义的链接:msdn.microsoft.com/en-us/library/windows/desktop/…

标签: c# marshalling intptr


【解决方案1】:

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 是一个结构体,定义为here:

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 的大小计算错误,因为它的定义不正确。当试图将指针转换为它们引用的结构时,下一个索引是错误的,因为大小已关闭。在转换内存块时,它可能引用了一个不应访问的块,抛出“拒绝访问(0x0000005)”错误。

【讨论】:

    猜你喜欢
    • 2019-07-20
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多