编组后字段中的值错误
Posted
技术标签:
【中文标题】编组后字段中的值错误【英文标题】:Wrong value in field after marshalling 【发布时间】:2013-01-04 16:02:54 【问题描述】:我正在尝试将原始结构从 C++ 编组为 C#,并具有以下代码:
using System;
using System.Runtime.InteropServices;
namespace dotNet_part
class Program
static void Main(string[] args)
Custom custom = new Custom();
Custom childStruct = new Custom();
IntPtr ptrToStructure = Marshal.AllocCoTaskMem(Marshal.SizeOf(childStruct));
Marshal.StructureToPtr(childStruct, ptrToStructure, true);
custom.referenceType = ptrToStructure;
custom.valueType = 44;
Custom returnedStruct = structureReturn(custom);
Marshal.FreeCoTaskMem(ptrToStructure);
returnedStruct = (Custom)Marshal.PtrToStructure(returnedStruct.referenceType, typeof(Custom));
Console.WriteLine(returnedStruct.valueType); // Here 'm receiving 12 instead of 44
[return:MarshalAs(UnmanagedType.I4)]
[DllImport("CPlusPlus part.dll")]
public static extern int foo(Custom param);
// [return:MarshalAs(UnmanagedType.Struct)]
[DllImport("CPlusPlus part.dll")]
public static extern Custom structureReturn(Custom param);
[StructLayout(LayoutKind.Sequential)]
struct Custom
[MarshalAs(UnmanagedType.I4)]
public int valueType;
public IntPtr referenceType;
还有C++部分:
typedef struct Custom CUSTOM;
extern "C"
struct Custom
int valueType;
Custom* referenceType;
Custom;
_declspec(dllexport) int foo(CUSTOM param)
return param.referenceType->valueType;
_declspec(dllexport) CUSTOM structureReturn(CUSTOM param)
return param;
为什么我在returnedStruct.valueType
中收到的是 12 而不是 44?
【问题讨论】:
这两个值相差32只是巧合吗?如果将 44 更改为 45,您的结果是否会从 12 更改为 13? 数值还是12,不管存哪个数字。 【参考方案1】:这里有两个错误:
从语义上讲,您正在设置 custom.valueType = 44
,但在返回结构时,您正在检查 custom.referenceType->valueType
,它不应该是 44——它应该是 0。
第二个错误是你在这个指针上调用Marshal.FreeCoTaskMem()
(custom.referenceType
)在你解组它之前!这意味着您正在将 未分配的内存 解组到您的 Custom
结构中。此时,这是未定义的行为,答案为 12 与收到访问冲突一样有效。
要解决第一个问题,您需要检查returnedStruct.valueType
无需解组returnedStruct.referenceType
,或者需要将childStruct.valueType
设置为44,然后再将其编组为ptrToStructure
。
要解决第二个问题,您需要颠倒调用Marshal.PtrToStructure()
和Marshal.FreeCoTaskMem()
的顺序。
【讨论】:
谢谢,现在解决方案很明显了。以上是关于编组后字段中的值错误的主要内容,如果未能解决你的问题,请参考以下文章