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

时间:2010-10-31 16:49:28

标签: c# c marshalling

我已经导出了以下要在DLL文件中调用的C函数。

uint8_t* _stdcall GetCurrentImage();

现在我想在C#中调用此函数来获取位图Image。 我怎么能这样做?

提前致谢!

3 个答案:

答案 0 :(得分:3)

您需要知道返回的确切字节数和位图尺寸(高度,宽度和编码)。然后你可以用C#声明它:

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

您从中获得的IntPtr可与Marshal.Copy一起使用,以获取原始字节:

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

最后,使用图片的尺寸和使用的Bitmap声明PixelFormat(如果它是非标准像素格式,您可能需要自己进行一些转换)。然后,您可以使用LockBits将数据复制到原始位图字节中,以获取指向原始位图数据的BitmapData实例。

答案 1 :(得分:0)

这样的事情的常见策略是传入缓冲区并让函数填充缓冲区。否则你会因处理分配的内存而遇到麻烦;换句话说,你会有内存泄漏。

所以你应该有这样的C函数......

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

然后在C#中你会做类似的事情......

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

// 'buffer' now contains the image

答案 2 :(得分:0)

如果你想在C#中继续在不安全的环境中工作,你也可以通过绕过Marshal和IntPtrs来简化一切:

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

请记住,在名为NativeMethods的静态类中插入所有导入并将其声明为内部导入始终是一种好习惯。