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

将C uint8_t指针转换为C#字节数组,c#,c,marshalling,C#,C,Marshalling,我已导出以下C函数,以便在DLL文件中调用 uint8_t* _stdcall GetCurrentImage(); 现在我想在C#中调用这个函数来获得位图图像。 我该怎么做 提前谢谢 您需要知道返回的确切字节数和位图尺寸(高度、宽度和编码)。然后您可以用C#声明它为: 从中获取的IntPtr可用于获取原始字节: byte[] buffer = new byte[length]; IntPtr beginPtr = GetCurrentImage(); Marshal.Copy(beginP

我已导出以下C函数,以便在DLL文件中调用

uint8_t* _stdcall GetCurrentImage();
现在我想在C#中调用这个函数来获得位图图像。 我该怎么做


提前谢谢

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

从中获取的IntPtr可用于获取原始字节:

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

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

此类操作的常见策略是传入缓冲区并让函数填充缓冲区。否则,在处理分配的内存时会遇到麻烦;换句话说,您将出现内存泄漏

所以你应该有这样的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

如果您想继续在不安全的环境中工作,即使是在C#中,也可以通过绕过封送和INTPTR来简化一切,如下所示:

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

请记住,将所有导入插入名为NativeMethods的静态类中并将其声明为internal始终是一种很好的做法。

谁将处理由
GetCurrentImage()
?@Timwi分配的内存,当然这取决于外部DLL中定义的约定。也许已经有一个函数可以实现这一点,或者可能需要添加它。但当然OP需要考虑到这一点。如果内存是在非托管代码中使用LocalAlloc分配的,则可以在托管代码中使用Marshal.FreeHGlobal来释放内存。明白了。。。唯一不太可能的是,24bppRGB的图片格式是BGR,而不是RGB
[DllImport("Library.dll")]
internal static unsafe extern Byte* GetCurrentImage();