我将一个结构数组的地址传递给外部程序的C#DLL。
我认为我会首先做一个简单的测试,以便通过尝试将指针编组到C#端的结构数组中来查看该方法是否有效。
给出以下结构:
[StructLayout(LayoutKind.Sequential)]
struct TestStruct
{
public int id;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string someString;
}
以下代码尝试读取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;
}
任何人都可以解释为什么,当我通过for循环调试时,只有第一个testStruct项正确地从指针编组?所有后续项目都包含字段中的垃圾,因为在第一次迭代后,指针地址显示不正确。
尺寸报告为36,这似乎是正确的。
我尝试使用显式布局,但这没有任何区别。
由于
答案 0 :(得分:0)
为什么你认为Marshal.StructureToPtr编组的东西比你告诉它要编组的更多?
Marshal.StructureToPtr(testStructs[0], ptrFirst, true);
将单个 TestStruct编组到ptrFirst
的内存中。
它基本上只是一个智能内存副本,它考虑了所有这些编组属性。
P.S。:并考虑到ptrFirst
的内存最多可以保留Marshal.SizeOf(testStructs[0])
。所以你不能(至少没有冒一些nasty memory access problem的风险)读取ptrFirst + size
后面的内存。