Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 正在将托管字节[]转换为结构[]_C#_.net_Struct_Casting_Pinvoke - Fatal编程技术网

C# 正在将托管字节[]转换为结构[]

C# 正在将托管字节[]转换为结构[],c#,.net,struct,casting,pinvoke,C#,.net,Struct,Casting,Pinvoke,考虑以下代码作为在struct[]和byte[]之间复制内存的示例。内存复制的方法与核心问题无关。它演示了指向托管数组的两个指针 [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)] public static extern void CopyMemory (IntPtr dest, IntPtr src, uint count); public struct MyStruct { public

考虑以下代码作为在
struct[]
byte[]
之间复制内存的示例。内存复制的方法与核心问题无关。它演示了指向托管数组的两个指针

[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
public static extern void CopyMemory (IntPtr dest, IntPtr src, uint count);

public struct MyStruct { public float Value; public TimeSpan Value; }

var bufferSize = 1000000;
var size = Marshal.SizeOf(typeof(MyStruct));
var bufferSource = new MyStruct [bufferSize];
var bufferTarget = new byte [bufferSize * size];

for (int i = 0; i < bufferSource.Length; i++)
{
    bufferSource [j] = new MyStruct() { Value = i; };
}

var handleSource = GCHandle.Alloc(bufferSource, GCHandleType.Pinned);
var handleTarget = GCHandle.Alloc(bufferTarget, GCHandleType.Pinned);
var pointerSource = handleSource.AddrOfPinnedObject();
var pointerTarget = handleTarget.AddrOfPinnedObject();
handleSource.Free();
handleTarget.Free();

CopyMemory(pointerTarget, pointerSource, (uint) (bufferSize * size));
[DllImport(“kernel32.dll”,EntryPoint=“CopyMemory”,SetLastError=false)]
公共静态外部无效CopyMemory(IntPtr dest、IntPtr src、uint count);
public struct MyStruct{public float Value;public TimeSpan Value;}
var bufferSize=1000000;
var size=Marshal.SizeOf(typeof(MyStruct));
var bufferSource=newmystruct[bufferSize];
var bufferTarget=新字节[bufferSize*size];
for(int i=0;i

IntPtr
pointerTarget
不是作为
MyStruct[]
发起的。是否有方法将此已分配和初始化的内存强制转换为
MyStruct[]
?我不想分配一个新的数组来执行此操作。

重新定义p/invoke签名更容易,在这种情况下,如下所示:

[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]
private static extern void CopyMemory([In, Out] byte[] pdst, Mystruct[] psrc, int cb);
CopyMemory(bufferTarget, bufferSource, bufferTarget.Length);
定义p/invoke的结构布局:

[StructLayout(LayoutKind.Sequential)]
public struct MyStruct { public float Value; public TimeSpan Value;}
然后你可以这样使用它:

[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]
private static extern void CopyMemory([In, Out] byte[] pdst, Mystruct[] psrc, int cb);
CopyMemory(bufferTarget, bufferSource, bufferTarget.Length);

你有没有尝试过改编这个-?@EugenePodskal:这个例子似乎是关于字节和结构之间的转换。这如何应用于将
字节[]
表示为
结构[]
?也许我遗漏了什么。如果你能从
byte[]
中获得
struct
,并且你知道结构的大小,那么从
byte[]
中获得多个
struct
有什么问题吗?@EugenePodskal:一次只给我一个
struct
。我的问题是如何以
struct[]
的形式访问内存,而不必重新分配内存(对于每个结构,使用
PtrToStructure
会发生这种情况)。部分理解,但你最好修改你的问题,以更清楚地表达你的目标,因为对我来说,这有点模糊和误导。那么,在C#代码中进行这种操作的原因是什么?指针通常在PInvoke中使用,.NET封送处理功能非常适合处理本机结构的数组。由于您使用的是
RtlMoveMemory
,因此我假设地址重叠不是问题。此签名的目标为
字节[]
。是否可以交换源和目标类型?如果是这样,那是因为存在这样的签名,还是因为运行时在内部负责封送处理?当然可以交换参数。这里没有编组。CLR只在您定义签名时使用它,并相应地发送内容。它几乎什么也不检查。由于您进入了非托管世界,如果签名错误,您将得到异常、错误,您可能会弄乱内存等等。在这里,因为它们被定义为数组,所以它将这些数组作为指针传递;您可以在以下位置查看文档:和