简体   繁体   English

将C uint8_t指针转换为C#字节数组

[英]Convert C uint8_t pointer to C# byte array

I have exported the following C function to be invoked in a DLL file. 我已经导出了要在DLL文件中调用的以下C函数。

uint8_t* _stdcall GetCurrentImage();

Now I want to call this function in C# to get a bitmap Image. 现在,我想在C#中调用此函数以获取位图图像。 How can I do this? 我怎样才能做到这一点?

Thanks in advance! 提前致谢!

You will need to know the exact number of bytes returned and the bitmap dimensions (height, width and encoding). 您将需要知道返回的确切字节数和位图尺寸(高度,宽度和编码)。 Then you can declare it in C# as: 然后,您可以在C#中将其声明为:

[DllImport("yourlib.dll")]
private static extern IntPtr GetCurrentImage();

The IntPtr you get from that can be used with Marshal.Copy , to get the raw bytes: 您从中获得的IntPtr可以与Marshal.Copy一起使用,以获取原始字节:

byte[]  buffer = new byte[length];
IntPtr beginPtr = GetCurrentImage();
Marshal.Copy(beginPtr, buffer,0,length);

Finally, declare a Bitmap with the dimensions of your image and the PixelFormat used (if it is a non-standard pixelformat, you might have to do some conversion yourself). 最后,声明一个具有图像尺寸和所用PixelFormatBitmap (如果它是非标准的pixelformat,则可能需要自己进行一些转换)。 Then you can copy the data into the raw bitmap bytes, by using LockBits to get a BitmapData instance that points to the raw bitmap data. 然后,您可以使用LockBits获取指向原始位图数据的BitmapData实例,将数据复制到原始位图字节中。

If you want to keep on working in an unsafe context even in C#, you can also simplify everything by bypassing Marshal and IntPtrs as follows: 如果要即使在C#中也要在不安全的上下文中继续工作,则还可以通过绕过Marshal和IntPtrs来简化一切,如下所示:

[DllImport("Library.dll")]
internal static unsafe extern Byte* GetCurrentImage();

Keep in mind that's always good practice to insert all of your imports in a static class called NativeMethods and declare them as internal. 请记住,将所有导入都插入到名为NativeMethods的静态类中并将它们声明为内部是一种好习惯。

The common strategy for things like this is to pass in a buffer and have the function fill the buffer. 诸如此类的通用策略是传入缓冲区并让函数填充缓冲区。 Otherwise you run into trouble with disposing of the memory allocated; 否则,您将在处理分配的内存时遇到麻烦; in other words, you will have a memory leak. 换句话说,您将发生内存泄漏。

So you should have C functions like this... 所以你应该有这样的C函数...

uint32_t _stdcall GetCurrentImageSize();
void _stdcall GetCurrentImage(uint8_t* buffer, int offset, int bufferSize);

And then in C# you would do something like... 然后在C#中,您将执行以下操作:

var buffer = new byte [ GetCurrentImageSize() ];
fixed (byte* b = &buffer[0])
    GetCurrentImage(b, 0, buffer.Length);

// 'buffer' now contains the image

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

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