如何解决如何将结构数组正确转换为.Net中的IntPtr
我在C ++中具有结构
struct {
CF_OPERATION_TRANSFER_PLACEHOLDERS_FLAGS Flags;
NTSTATUS CompletionStatus;
LARGE_INTEGER PlaceholderTotalCount;
CF_PLACEHOLDER_CREATE_INFO *PlaceholderArray;
DWORD PlaceholderCount;
DWORD EntriesProcessed;
} TransferPlaceholders;
并将其编组到.Net:
[StructLayout(LayoutKind.Sequential)]
public struct TRANSFERPLACEHOLDERS
{
/// <summary>Flags for transferring placeholders.</summary>
public CF_OPERATION_TRANSFER_PLACEHOLDERS_FLAGS Flags;
/// <summary>The completion status of the operation.</summary>
public NTStatus CompletionStatus;
/// <summary>Total number of placeholders.</summary>
public long PlaceholderTotalCount;
/// <summary>An array of placeholders to be transferred.</summary>
public IntPtr PlaceholderArray;
/// <summary>The number of placeholders being transferred.</summary>
public uint PlaceholderCount;
/// <summary>The placeholder entries that have been processed.</summary>
public uint EntriesProcessed;
}
CF_PLACEHOLDER_CREATE_INFO编组:
[PInvokeData("cfapi.h",MSDNShortId = "2DC1FF5F-FBFD-45CA-8CD5-B2F586C22778")]
[StructLayout(LayoutKind.Sequential)]
public struct CF_PLACEHOLDER_CREATE_INFO
{
/// <summary>The name of the child placeholder file or directory to be created.</summary>
[MarshalAs(UnmanagedType.LPWStr)]
public string RelativeFileName;
/// <summary>File system Metadata to be created with the placeholder.</summary>
public CF_FS_MetaDATA FsMetadata;
/// <summary>
/// A user mode buffer containing file information supplied by the sync provider. This is required for files (not for directories).
/// </summary>
public IntPtr FileIdentity;
/// <summary>Length,in bytes,of the <c>FileIdentity</c>.</summary>
public uint FileIdentityLength;
/// <summary>Flags for specifying placeholder creation behavior.</summary>
public CF_PLACEHOLDER_CREATE_FLAGS Flags;
/// <summary>The result of placeholder creation. On successful creation,the value is: STATUS_OK.</summary>
public HRESULT Result;
/// <summary>The final USN value after create actions are performed.</summary>
public int CreateUsn;
}
因此,我需要将结构CF_PLACEHOLDER_CREATE_INFO的数组传递给IntPtr PlaceholderArray。 我试图通过这种方式转换结构数组:
aPlaceholders.MarshalToPtr(Marshal.AllocHGlobal,out _);
但是我只接收数组第一个元素的指针。因此,如果数组大小为1,则可以使用。否则,我将收到Acess Violation 0xFFFFFFFFFFFFFF。 还试图使用此功能一张一张地复制数组的每个元素:
public void MarshalUnmananagedArray2Struct<T>(IntPtr unmanagedArray,int length,out T[] mangagedArray)
{
var size = Marshal.SizeOf(typeof(T));
mangagedArray = new T[length];
for (int i = 0; i < length; i++)
{
IntPtr ins = new IntPtr(unmanagedArray.ToInt64() + i * size);
mangagedArray[i] = Marshal.PtrToStructure<T>(ins);
}
}
并且具有绝对相同的行为,仅在数组大小为1的情况下有效。 我猜我在将数组转换为IntPtr时做错了。会很高兴为您提供帮助!
public static IntPtr MarshalToPtr<T> (this IEnumerable<T> items,Func<int,IntPtr> memAlloc,out int bytesAllocated,int prefixBytes = 0)
{
if (!typeof (T).IsMarshalable ()) throw new ArgumentException (@"Structure layout is not sequential or explicit.");
bytesAllocated = prefixBytes;
var count = items?.Count () ?? 0;
if (count == 0) return memAlloc (bytesAllocated);
var sz = Marshal.SizeOf (typeof (T));
bytesAllocated += sz * count;
var result = memAlloc (bytesAllocated);
result.Write (items,prefixBytes,bytesAllocated);
return result;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。