c#将文件指针传递给非托管c ++ dll以用于stdout

时间:2011-10-02 15:09:17

标签: c# c++ pointers stdout

请耐心等待我 - 我是一名C#开发人员,对C ++经验不足,这是一个陡峭的学习曲线!

从c#控制台应用程序,我正在从非托管C ++ dll调用一些方法。 DLL写入stdout流,尽管c#console没有提取它。

我找到了以下代码,我将其添加到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 );
}

到目前为止AOK:

我想要做的是将stdout从DLL捕获到c#流,而不是将其发送到控制台。我尝试了这里详述的方法(Redirect stdout+stderr on a C# Windows service),它捕获了输出,但程序关闭时应用程序“崩溃”(“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#Console应用程序关闭时,应用程序崩溃时出现错误“vshost.exe已停止工作”。这与我使用Redirect stdout+stderr on a C# Windows service

中的方法时的错误相同

奇怪的发现:如果我在“视觉工作室之外”运行控制台应用程序(例如,双击bin文件夹中的.exe),就没有崩溃!

所以我想我的下一个问题是:如何追踪此次崩溃的来源? VS相关吗?从VS运行时,它在调试或释放模式下发生,在VS外部运行时不会发生崩溃。

我不知道如何调试这个!

1 个答案:

答案 0 :(得分:1)