我正在尝试将原始结构从 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?
最佳答案
这里有两个错误:
从语义上讲,您正在设置 custom.valueType = 44
但在返回结构时,您正在检查 custom.referenceType->valueType
,它不应该是 44 - - 它应该是 0。
第二个错误是您在解码之前在此指针 (custom.referenceType
) 上调用 Marshal.FreeCoTaskMem()
!这意味着您正在将未分配的内存 解码到您的Custom
结构中。在这一点上,这是未定义的行为,答案 12 与收到访问冲突一样有效。
要解决第一个问题,您需要检查 returnedStruct.valueType
没有解码 returnedStruct.referenceType
,或者您需要设置 childStruct.valueType
到 44,然后再将其编码到 ptrToStructure
。
要解决第二个问题,您需要颠倒调用 Marshal.PtrToStructure()
和 Marshal.FreeCoTaskMem()
的顺序。
关于c# - 编码后字段中的错误值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14160512/