c# 将文件指针传递给非托管 c++用于标准输出的 dll
请耐心等待 - 我是一名 c# 开发人员,几乎没有 C++ 经验,这是一个陡峭的学习曲线!
从 ac# 控制台应用程序中,我从非托管 C++ dll 调用一些方法。 DLL 写入 stdout 流,尽管 c# 控制台并未拾取该流。
我找到了以下代码,将其添加到 C++ dll 中,现在它成功地将“printf”的内容发送到 c# 控制台。
#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
void redirect_stdout()
{
int hConHandle;
long lStdHandle;
FILE *fp;
// allocate a console for this app
AllocConsole();
// redirect unbuffered STDOUT to the console
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
}
到目前为止还可以:
我想做的是将 DLL 中的标准输出捕获到 ac# 流,而不是将其发送到控制台。我尝试了此处详细说明的方法(在 C# Windows 服务上重定向 stdout+stderr ),它确实捕获了输出,但是当程序关闭时应用程序“崩溃”(“vshost.exe 已停止工作”)。
(注意:在流上设置 Console.SetOut() 会捕获 C# 输出,而不是 C++ 输出)。
所以我想如果我使用“Filestream.SafeFileHandle.DangerousGetHandle()
”方法从 C# 获取文件流的句柄,并将其传递到 C++ 方法的 redirect_stdout() 方法中会怎样:
void redirect_stdout(FILE *passedInHandle)
{
// allocate a console for this app
AllocConsole();
*stdout= *passedInHandle;
setvbuf( stdout, NULL, _IONBF, 0 );
}
当我运行时在上面的版本中,DLL 的输出不再通过管道传输到 C# 控制台,但是,C# 端的文件流始终为空。
任何专家都可以指导如何让 STDOUT 将其输出写入 c# 文件流吗?我确信我在如何实现这一目标方面犯了一些愚蠢的错误,或者我不明白如何实现我想要做的事情。
感谢您的时间和投入 - 非常感谢!
[编辑]
好的 - 我玩得更多一些并修改了 C++ 方法,如下所示:
void redirect_stdout(int passedInHandle)
{
int hConHandle;
long lStdHandle;
FILE *fp;
// allocate a console for this app
AllocConsole();
hConHandle = _open_osfhandle(passedInHandle, _O_TEXT);
fp = _fdopen(hConHandle, "w");
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
}
这也成功填充了 c# 流,但是当 c# 控制台应用程序关闭时,应用程序崩溃并出现错误“ vshost.exe 已停止工作”。这与我使用 在 C# Windows 上重定向 stdout+stderr 中的方法时出现的错误相同服务
非常奇怪的发现: 如果我“在 Visual Studio 之外”运行控制台应用程序(例如,双击 bin 文件夹中的 .exe),则不会崩溃!
所以我想我的下一个问题是:如何追踪这次崩溃的根源?与VS有关吗?从 VS 运行时,它会在调试或发布模式下发生,而在 VS 之外运行时不会崩溃。
我不知道如何调试这个!
Please bear with me - I'm a c# developer with little experience with C++, and this is a steep learning curve!
From a c# console app, I'm calling some methods from an unmanaged C++ dll. The DLL writes to the stdout stream, although this was not being picked up by the c# console.
I found the following code, which I added to the C++ dll, which now successfully sends the contents of "printf" to the c# console.
#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
void redirect_stdout()
{
int hConHandle;
long lStdHandle;
FILE *fp;
// allocate a console for this app
AllocConsole();
// redirect unbuffered STDOUT to the console
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
}
AOK so far:
What I'd like to do is capture the stdoutfrom the DLL to a c# stream, rather than send it to the console. I tried the method detailed here (Redirect stdout+stderr on a C# Windows service), which does capture the output, however the app "crashes" when the program closes ("vshost.exe has stopped working").
(Note: setting Console.SetOut() on the stream captures the c# output, not the c++ output).
So I thought what if I use the "Filestream.SafeFileHandle.DangerousGetHandle()
" method to get a handle to the filestream from c#, and pass this into the C++ method redirect_stdout() method:
void redirect_stdout(FILE *passedInHandle)
{
// allocate a console for this app
AllocConsole();
*stdout= *passedInHandle;
setvbuf( stdout, NULL, _IONBF, 0 );
}
When I run the above version, the output from the DLL is no longer piped to the c# Console, however, the filestream on the c# side is always empty.
Can any expert give guidance to have the STDOUT write its output to the c# filestream? I'm sure I've made some stupid error about how to achieve this or I am not understanding how to achieve what I am trying to do.
Thank you for your time and input - really appreciated!
[EDIT]
OK - I've played a bit more and modified the C++ method as such:
void redirect_stdout(int passedInHandle)
{
int hConHandle;
long lStdHandle;
FILE *fp;
// allocate a console for this app
AllocConsole();
hConHandle = _open_osfhandle(passedInHandle, _O_TEXT);
fp = _fdopen(hConHandle, "w");
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
}
This also successfully populates the c# stream, however when the c# Console app closes, the app crashes with the error "vshost.exe has stopped working". This is the same error as when I use the method from Redirect stdout+stderr on a C# Windows service
Very odd find: If I run the console app "outside of visual studio" (eg, double click on the .exe in the bin folder), there is no crash!
So I guess my next question is: how do I track down the source of this crash? Is it VS related? It occurs in either debug or release mode when running from VS, and no crash when run outside of VS.
I am at a loss as to how to debug this one!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以考虑使用命名管道:即
c++和c#之间通过管道进行通信
http://www.switchonthecode.com/tutorials/interprocess-communication-using-named-pipes-in-csharp
希望这应该有效......
You might consider using named pipes: i.e
communication between c++ and c# through pipe
http://www.switchonthecode.com/tutorials/interprocess-communication-using-named-pipes-in-csharp
Hopefully, that should work...