简体   繁体   English

从IntPtr整理结构数组-仅第一个值正确整理

[英]Marshalling Array of Struct from IntPtr - Only First Value Marshals Correctly

I'm passing an address to an array of structures into a C# DLL from an external program. 我正在从外部程序将地址传递给结构数组到C#DLL中。

I thought that I would first make a simple test, in order to see if the approach would work, by trying to marshal a pointer into an array of structs on the C# side. 我以为我会先尝试通过将指针编组到C#端的结构数组中来进行简单测试,以查看该方法是否可行。

Given the following struct: 给定以下结构:

[StructLayout(LayoutKind.Sequential)]
struct TestStruct
{
    public int id;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    public string someString;
}

and the following code which attempts to read the struct array (the section up until the for loop is just to simulate the pointer being passed from the other program): 下面的代码尝试读取struct数组(直到for循环的那一部分只是为了模拟从其他程序传递来的指针):

TestStruct[] testStructs = new TestStruct[3];
testStructs[0].id = 1;
testStructs[0].someString = "Value 1";
testStructs[1].id = 2;
testStructs[1].someString = "Value 2";
testStructs[2].id = 3;
testStructs[2].someString = "Value 3";

int size = Marshal.SizeOf(testStructs[0]);
IntPtr ptrFirst = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(testStructs[0], ptrFirst, true);

long ptrAddrLong = ptrFirst.ToInt64();

for (int i = 0; i < testStructs.Length; i++) {
    IntPtr thisPtr = new IntPtr(ptrAddrLong);
    TestStruct testStruct = Marshal.PtrToStructure<TestStruct>(thisPtr);
    ptrAddrLong += size;
}

can anyone shed any light why, when I debug through the for loop, only the first testStruct item is marshalled correctly from the pointer? 谁能阐明为什么,当我通过for循环调试时,只有第一个testStruct项从指针正确编组了? All subsequent items contain garbage in the fields, as it appears the pointer address is incorrect after the first iteration. 所有后续项在字段中都包含垃圾,因为在第一次迭代后,指针地址似乎不正确。

First iteration: 第一次迭代: 在此处输入图片说明

Second iteration: 第二次迭代: 在此处输入图片说明

Size is reported as 36, which seems to be correct. 大小报告为36,这似乎是正确的。

I've tried using explicit layout, but this didn't make any difference. 我尝试使用显式布局,但这没有任何区别。

Thanks 谢谢

Why do you think that Marshal.StructureToPtr marshals anything more than you have told it to marshal? 为什么您认为Marshal.StructureToPtr会比您已告知的任何其他方式进行封送?

Marshal.StructureToPtr(testStructs[0], ptrFirst, true); marshals a single TestStruct to the memory at ptrFirst . 编组的单个 TestStruct于在存储器ptrFirst

It is basically just a smart memory copy that takes into account all those marshaling attributes. 基本上,它只是考虑所有这些封送处理属性的智能内存副本。

PS: And take into account that memory at ptrFirst can hold at most Marshal.SizeOf(testStructs[0]) . PS:考虑到ptrFirst内存ptrFirst可以容纳Marshal.SizeOf(testStructs[0]) So you can't (at least without risking some nasty memory access problem ) read a memory behind ptrFirst + size . 因此,您(至少不会冒一些讨厌的内存访问问题的风险) 无法读取ptrFirst + size之后的内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM