简体   繁体   English

c#使用Marshal.Copy()将结构数组复制为字节

[英]c# copy array of structures as bytes using Marshal.Copy()

I'm having a problem with copying an array of structures as a byte array. 我在将结构数组复制为字节数组时遇到问题。 The structures are simple RGB structs. 结构是简单的RGB结构。

public struct RGBColor { byte r; byte g; byte b; }

Then I have an array of RGBColor[] that represents a scanline that I want to copy to a Bitmap after I've called LockBits() . 然后,我有一个RGBColor[]数组,它表示要在调用LockBits()之后复制LockBits() Bitmap的扫描线。 It will only allow an array of byte[] to be copied using Marshal.Copy() . 它仅允许使用Marshal.Copy()复制byte[]数组。

If I understand correctly (keep in mind I DO NOT UNDERSTAND), I need to marshal the RGBColor[] array to a byte array, copy the data to that new byte[] array, and then copy that array to the bitmap. 如果我理解正确(请记住我不要理解),则需要将RGBColor[]数组编组为字节数组,将数据复制到新的byte[]数组,然后将该数组复制到位图。 It seems like there's an unnecessary copying operation occuring and I have an intermediate byte[] array just serving as a middle man. 似乎正在发生不必要的复制操作,并且我有一个中间的byte[]数组仅用作中间人。

Isn't there any way I can cast RGBColor[] to byte[] so I can just copy it directly to the locked bitmap? 有什么方法可以将RGBColor[]byte[]以便直接将其复制到锁定的位图吗?

Marshal.Copy() isn't the right method in this case, it forces you to cough up the byte[] and that hurts in more than one way. 在这种情况下,Marshal.Copy()不是正确的方法,它会迫使您咳嗽byte [],这会以多种方式造成伤害。 What you really need is a method that copies from an IntPtr to an IntPtr so that simply pinning the array gets the job done, avoiding the copy and the structure layout hassle. 您真正需要的是一种从IntPtr复制到IntPtr的方法,这样只需固定阵列即可完成工作,避免了复制和结构布局的麻烦。 The .NET framework doesn't have one. .NET框架没有一个。

But Windows does, you can pinvoke the memcpy() function. 但是Windows确实可以调用memcpy()函数。 You can tinker the declaration to make it accept your RGBColor[] array. 您可以修改声明,使其接受您的RGBColor []数组。 Like this: 像这样:

  [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
  private static extern int memcpy(IntPtr dest, RGBColor[] srce, int bytes);

The first argument is slightly tricky. 第一个论点有些棘手。 You'll need: 你需要:

  BitmapData bd = ...
  IntPtr dest = new IntPtr((long)bd.Scan0 + scanline * bd.Stride);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM