Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.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# 从IntPtr封送结构数组-仅第一个值正确封送_C#_Marshalling - Fatal编程技术网

C# 从IntPtr封送结构数组-仅第一个值正确封送

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; } 下

我将一个地址从外部程序传递到一个C#DLL的结构数组中

我想我首先要做一个简单的测试,通过尝试将指针封送到C#端的结构数组中,看看这种方法是否有效

给定以下结构:

[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;
}