如何将数据从托管程序集流式传输到本机库并再次返回?

发布于 2024-12-22 01:35:39 字数 1536 浏览 0 评论 0原文

如何将数据(文本)从托管程序集流式传输到本机库并将数据(文本)流回托管程序集?

具体来说,我想在 .NET 端公开某种 System.IO.Stream ,以及(最重要的)一个 FILE *在本机方面。

本机方法的签名应为:

FILE * foo(FILE * bar);

围绕本机 p/invoke 调用的包装器的签名应为:

CustomStream foo(CustomStream bar);

我不想在本机端使用回调方法(一种用于获取更多数据,另一种用于设置更多数据)。我想在本机端使用 FILE * - 以及对其进行操作的所有关联方法,例如 fprintf

我不需要任何磁盘 I/O。这需要是内存中操作。

我可以完全控制托管程序集和本机库。

该解决方案必须与 .NET 2.0 一起使用,

我愿意创建实现此目标所需的任何类型的托管或非托管填充层。

“明显”的解决方案是使用 STDIN 和 STDOUT 并启动子进程 - 但我不想要单独的进程。另外,我尝试重定向本机库的 STDINSTDOUT 流(该库不是 Windows 上的控制台应用程序),但失败了一些(并且令人头疼) 。

基于这个问题: 在 C# Windows 服务上重定向 stdout+stderr 我尝试修改(至少)解决我的问题的“响应”流一半的方法 - 但没有 FileStream (因为我想要更类似于内存流)。但是,FileStream 是唯一公开合适的低级流句柄的流类型。

否则,我就陷入了困境,目前我认为我需要更深入地研究并提出我自己的手动本地<->托管流实现,但真的不知道从哪里开始。


终于解决了

我在这里发布了一个完整的示例项目:

http://pastebin.com/jcjHdnwz

这是针对 .NET 的3.5 并使用 AnonymousPipeServerStream - 但通过一点反射器,很容易复制其内部工作原理.NET 2.0 中的 AnonymousPipeServerStream。

感谢您的帮助 shf301 向我指出了本机管道 API,这让我研究了 Microsoft 文档以更好地了解正在发生的事情,并指出我需要使用 _open_osfhandle 方法来获取 FILE * 引用。

How can I stream data (text) from a managed assembly to a native library and stream data (text) back to the managed assembly?

Specifically, I want to expose a System.IO.Stream of some sort on the .NET side, and (most importantly) a FILE * on the native side.

The signature of the native method should be:

FILE * foo(FILE * bar);

The signature of a wrapper around the native p/invoke call should be:

CustomStream foo(CustomStream bar);

I do not want to use callback methods on the native side (one for getting more data and one for setting more data). I want to use a FILE * on the native side - and all of the associated methods which operate upon it such as fprintf.

I do not want any disk I/O. This needs to be an in-memory operation.

I have complete control over both the managed assembly and the native library.

The solution must work with .NET 2.0

I'm willing to create any sort of managed or unmanaged shim layer required to pull this off.

The "obvious" solution is to use STDIN and STDOUT and launch a child process - however I don't want a separate process. Also, my attempts to redirect the STDIN and STDOUT streams of a native library which isn't a console application on Windows have failed somewhat spectacularly (and with much head-banging).

Based on this question:
Redirect stdout+stderr on a C# Windows service I attempted to modify the approach to (at least) solve the "response" stream half of my problem - but without a FileStream (since I want something more analogous to a MemoryStream). However, FileStream is the only stream type which exposes a suitable low-level stream handle.

Otherwise, I'm pretty well stuck and am currently thinking I'll need to dive deeper and come up with my own hand-rolled native<->managed stream implementation but don't really know where to start.


Solution

Finally!

I've posted a complete sample project here:

http://pastebin.com/jcjHdnwz

This is for .NET 3.5 and uses the AnonymousPipeServerStream - but with a little bit of reflector-ing, it's easy enough to duplicate the inner workings of the AnonymousPipeServerStream in .NET 2.0.

Thanks for your help shf301 for pointing me to the native pipe API, which got me looking into the Microsoft docs for a better understanding of what's going on, and for pointing out I needed to use the _open_osfhandle method to get the FILE * reference.

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

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

发布评论

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

评论(1

醉酒的小男人 2024-12-29 01:35:39

您应该能够使用 AnonymousPipeStream 在 .NET 3.5 或更高版本中。这会通过 SafePipeHandle 属性公开一个句柄,您可以将其传递给 SetStdHandle

对于 .NET 2.0,您可能必须 P/Invoke 到非托管管道 API。

You should be able to do this using a AnonymousPipeStream in .NET 3.5 or higher. That exposes a handle, via the SafePipeHandle property that you can pass to SetStdHandle.

For .NET 2.0 you may have to P/Invoke to the unmanaged pipe API.

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