包含字节数组的编组结构
Posted
技术标签:
【中文标题】包含字节数组的编组结构【英文标题】:Marshalling structures containing byte array 【发布时间】:2014-10-03 08:14:02 【问题描述】:第二天,我一直在努力解决如何将包含字节数组的结构传递给 c++ dll 的任务。即,我不知道如何编组 C# 结构。这是我的代码:
in C++ dll:
struct Image
int Width;
int Height;
int Depth;
uchar *Data;
;
.....
__declspec(dllexport) void DirectTransform(Image *InImage, Image*DestImage)
...Implementation...
在 C# 程序中:
[StructLayout(LayoutKind.Sequential)]
struct ImageData
public int Width;
public int Height;
public int Depth;
[MarshalAs(UnmanagedType.LPArray)]
public byte[] Data;
[DllImport("MyDll.dll",CallingConvention=CallingConvention.Cdecl)]
public static extern void DirectTransform(ImageData Src, ImageData Dest);
//Fill out both structures..
DirectTransform(Image, DestImage);
调用 DirectTransform 时抛出异常并表示:
无法封送类型为“ImageData”的字段“数据”:托管/非托管无效 类型组合(数组字段必须与 ByValArray 或 安全阵列)。
当我将 LPArray 更改为 ByValArray 并指向数组的大小(在本例中为 202500)它也不起作用,因为大小太大。使用 SafeArray 时,程序在 DLL 中失败并显示以下消息:
试图读取或写入受保护的内存。这通常是一个 指示其他内存已损坏。 并且结构中的数据是错误的。
谁能帮帮我?
【问题讨论】:
必须是 IntPtr,用 Marshal.AllocHGlobal() 初始化。然而,Dest 参数是一个问题,您要么不知道要分配多大的数组,要么 C 代码分配了它,然后您就会发生内存泄漏。 【参考方案1】:看看这个question
您可以尝试将指针传递给您的数组,例如整数长度字段。
这样做,您需要使用 Marshal.AllocHGlobal
手动分配非托管内存,调用您的函数,然后在 finally
块中 - 使用 Marshal.FreeHGlobal
自行清除
使用Marshal.Copy
方法,您可以将数据复制到分配的内存中。
【讨论】:
以上是关于包含字节数组的编组结构的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Parcel 的帮助下将 Parcelable 编组和解组为字节数组?