1

structの から の の配列を構築する際に問題があります。IntPtrstruct

この構造は、私が使用している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);

DFS_STORAGE_INFO_1によって参照されるの配列を取得しようとしていIntPtr Storageます。

その構造は次のとおりです(重要な場合):

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_91 つのストレージのみで s を取得するように機能していますが、配列内の 2 番目の項目をマーシャリングしようとすると失敗します。

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 つある可能性がある で発生しています。私の考えが間違っているのかもしれませんが、これを修正する方法がわかりません。

4

1 に答える 1

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 は構造体で、ここで定義されています:

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)」エラーがスローされました。

于 2013-04-08T14:24:19.660 に答える