C# 从IntPtr封送结构数组-仅第一个值正确封送
我将一个地址从外部程序传递到一个C#DLL的结构数组中 我想我首先要做一个简单的测试,通过尝试将指针封送到C#端的结构数组中,看看这种方法是否有效 给定以下结构:C# 从IntPtr封送结构数组-仅第一个值正确封送,c#,marshalling,C#,Marshalling,我将一个地址从外部程序传递到一个C#DLL的结构数组中 我想我首先要做一个简单的测试,通过尝试将指针封送到C#端的结构数组中,看看这种方法是否有效 给定以下结构: [StructLayout(LayoutKind.Sequential)] struct TestStruct { public int id; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string someString; } 下
[StructLayout(LayoutKind.Sequential)]
struct TestStruct
{
public int id;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string someString;
}
下面的代码尝试读取struct数组(直到for循环的部分只是模拟从另一个程序传递的指针):
TestStruct[]testStructs=newteststruct[3];
testStructs[0]。id=1;
testStructs[0].someString=“值1”;
testStructs[1].id=2;
testStructs[1].someString=“值2”;
testStructs[2].id=3;
testStructs[2].someString=“值3”;
int size=Marshal.SizeOf(testStructs[0]);
IntPtr ptrFirst=Marshal.AllocHGlobal(大小);
StructureToPtr(testStructs[0],ptrFirst,true);
long ptrAddrLong=ptrFirst.ToInt64();
for(int i=0;i
有人能解释一下为什么当我调试for循环时,只有第一个testStruct项从指针正确编组吗?所有后续项在字段中都包含垃圾,因为在第一次迭代后指针地址似乎不正确
第一次迭代:
第二次迭代:
大小报告为36,这似乎是正确的
我尝试过使用显式布局,但没有任何区别
谢谢为什么你认为这封邮件比你告诉它封送的要多
Marshal.StructureToPtr(testStructs[0],ptrFirst,true)
将单个TestStruct封送到ptrFirst
处的内存中
它基本上只是一个考虑了所有封送属性的智能内存拷贝
p.S.:并考虑到
ptrFirst
的内存最多只能容纳marshall.SizeOf(testStructs[0])
。因此,您不能(至少在不冒一些风险的情况下)读取ptrFirst+size
后面的内存。在for循环之前,代码的第一部分旨在模拟从另一个程序接收指针。我认为可以在for循环中增加指针值,将指针地址封送到一个结构中,以迭代方式访问数组的每个元素。如果这不是正确的方法,你能给我指出正确的方向吗?我想我明白你的意思了。我实际上并没有得到一个指向现有数组的指针,是不是,我正在将一个新的、单个的TestStruct编组到一个新的内存块,这解释了为什么后续的值都是垃圾。@流氓,但在实际代码中,您有一些IntPtr指向一个实际的TestStruct
s数组,对吗?另外,如果您想创建这样的IntPtr进行演示,您可以查看基本上是按顺序封送TestStruct数组的元素,然后使用第一个指针开始模拟。谢谢你,这应该达到我想要的。我现在不太擅长处理非托管的东西。
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;
}