2016-02-27 36 views
0

我从一个外部程序将地址传递给一个结构数组成一个C#DLL。从IntPtr编组结构数组 - 只有第一个值正确编组

我想我会首先进行一个简单的测试,以便通过尝试将指针编组到C#端的结构数组中来查看该方法是否可行。

鉴于下面的结构:

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

和下面的代码试图读取结构阵列(该部分直到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项从指针正确编组?所有后续项目都包含字段中的垃圾,因为第一次迭代后指针地址不正确。

第一次迭代: enter image description here

第二次迭代: enter image description here

面积报告为36,这似乎是正确的。

我试过使用显式布局,但是这没有任何区别。

感谢

回答

0

为什么你认为Marshal.StructureToPtr编组任何超过你告诉它元帅?

Marshal.StructureToPtr(testStructs[0], ptrFirst, true); marshals a single TestStruct到内存ptrFirst

它基本上只是一个智能内存副本,将所有这些封送处理属性考虑在内。

P.S:而且考虑到内存ptrFirst可容纳最多Marshal.SizeOf(testStructs[0])。所以你不能(至少不冒险一些nasty memory access problem)读取ptrFirst + size背后的内存。

+0

代码的第一部分,在for循环之前,旨在模拟从另一个程序接收指针。我认为可以在for循环中增加指针值,将指针地址编组为一个结构,以迭代访问数组中的每个元素。如果这不是正确的方法,请你指点我正确的方向? – Hoodlum

+0

我想我明白你的意思了。我实际上并没有得到一个指向现有数组的指针,我正在将一个新的单个TestStruct编组为一段新的内存,这就解释了为什么后续值是垃圾。 – Hoodlum

+0

@Hoodlum但是在实际的代码中,你有一些指向'TestStruct'的实际数组的IntPtr,我正确吗?另外,如果你想创建这样的IntPtr进行演示,你可以看看http://stackoverflow.com/questions/1086294/convert-array-of-structs-to-intptr –

相关问题