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

发布于 2024-09-29 19:38:33 字数 146 浏览 3 评论 0原文

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

uint8_t* _stdcall GetCurrentImage();

现在我想在C#中调用这个函数来获取位图图像。 我该怎么做?

提前致谢!

I have exported the following C function to be invoked in a DLL file.

uint8_t* _stdcall GetCurrentImage();

Now I want to call this function in C# to get a bitmap Image.
How can I do this?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

镜花水月 2024-10-06 19:38:33

您需要知道返回的确切字节数和位图尺寸(高度、宽度和编码)。然后,您可以在 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);

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

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:

[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:

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). 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.

爺獨霸怡葒院 2024-10-06 19:38:33

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

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

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...

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

And then in C# you would do something like...

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

// 'buffer' now contains the image
失退 2024-10-06 19:38:33

如果您想继续在不安全的上下文中工作,即使在 C# 中,您也可以通过绕过 Marshal 和 IntPtrs 来简化一切,如下所示:

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

请记住,将所有导入插入到名为 NativeMethods 的静态类中并声明它们始终是一个好的做法作为内部。

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:

[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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文