如何将 stdout 重定向到 Windows 应用程序中的某些可见显示?
我可以访问一个做“好东西”的第三方库。 它向标准输出发出状态和进度消息。 在控制台应用程序中,我可以很好地看到这些消息。 在 Windows 应用程序中,它们只是转到位存储桶。
是否有一种相当简单的方法将 stdout 和 stderr 重定向到文本控件或其他可见位置。 理想情况下,这不需要重新编译第三方代码。 它只会拦截低水平的蒸汽。 我想要一个解决方案,我只需 #include 标头,调用初始化函数并链接库,如下所示...
#include "redirectStdFiles.h"
void function(args...)
{
TextControl* text = new TextControl(args...);
initializeRedirectLibrary(text, ...);
printf("Message that will show up in the TextControl\n");
std::cout << "Another message that also shows up in TextControl\n";
}
更好的是,如果它使用一些我可以覆盖的接口,这样它就不会绑定到任何特定的 GUI 库。
class StdFilesRedirector
{
public:
writeStdout(std::string const& message) = 0;
writeStderr(std::string const& errorMessage) = 0;
readStdin(std::string &putReadStringHere) = 0;
};
我只是在做梦吗? 或者有人知道可以做这样的事情吗?
在两个答案后编辑:我认为使用 freopen 重定向文件是一个很好的第一步。 对于完整的解决方案,需要创建一个新线程来读取文件并显示输出。 对于调试,在 cygwin shell 窗口中执行“tail -f”就足够了。 对于更精致的应用程序...这就是我想写的...需要一些额外的工作来创建线程等。
I have access to a third party library that does "good stuff." It issues status and progress messages to stdout. In a Console application I can see these messages just fine. In a Windows application they just go to the bit bucket.
Is there a fairly simple way to redirect stdout and stderr to a text control or other visible place. Ideally, this would not require any recompiles of the third party code. It would just intercept the steams at a low level. I'd like a solution where I just #include the header, call the initialization function and link the library as in...
#include "redirectStdFiles.h"
void function(args...)
{
TextControl* text = new TextControl(args...);
initializeRedirectLibrary(text, ...);
printf("Message that will show up in the TextControl\n");
std::cout << "Another message that also shows up in TextControl\n";
}
Even better would be if it used some interface that I could override so it is not tied to any particular GUI library.
class StdFilesRedirector
{
public:
writeStdout(std::string const& message) = 0;
writeStderr(std::string const& errorMessage) = 0;
readStdin(std::string &putReadStringHere) = 0;
};
Am I just dreaming? Or does anyone know of something that can do something like this?
Edit after two answers: I think using freopen to redirect the files is a good first step. For a complete solution there would need to be a new thread created to read the file and display the output. For debugging, doing a 'tail -f' in a cygwin shell window would be enough. For a more polished application... Which is what I want to write... there would be some extra work to create the thread, etc.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
您需要创建管道(使用 CreatePipe() ),然后使用 SetStdHandle()< 将标准输出附加到其写入端/a>,然后您可以使用 ReadFile 从管道的读取端读取() 并将您从那里获得的文本放在您喜欢的任何地方。
You need to create pipe (with CreatePipe()), then attach stdout to it's write end with SetStdHandle(), then you can read from pipe's read end with ReadFile() and put text you get from there anywhere you like.
您可以使用 freopen 重定向 stdout、stderr 和 stdin。
从上面的链接:
您还可以通过命令提示符运行您的程序,如下所示:
You can redirect stdout, stderr and stdin using freopen.
From the above link:
You can also run your program via command prompt like so:
您可能正在寻找类似的东西:
这个类会做到这一点:
结果如下:
You're probably looking for something along those lines:
This class will do it:
Here's the result:
当您使用 CreateProcess() 创建进程时,您可以选择 < code>HANDLE 将写入 stdout 和 stderr。 此
HANDLE
可以是您将输出定向到的文件。这将使您无需重新编译即可使用代码。 只需执行它,而不是使用
system()
或诸如此类的东西,而是使用CreateProcess()
。您提供给
CreateProcess()
的 HANDLE 也可以是您创建的管道的句柄,然后您可以从管道中读取数据并对数据执行其他操作。When you create a process using CreateProcess() you can choose a
HANDLE
to which stdout and stderr are going to be written. ThisHANDLE
can be a file to which you direct the output.This will let you use the code without recompiling it. Just execute it and instead of using
system()
or whatnot, useCreateProcess()
.The HANDLE you give to
CreateProcess()
can also be that of a pipe you created, and then you can read from the pipe and do something else with the data.您可以使用 cout 或 cerr 执行类似的操作:
或者,您可以使用 std::stringstream 或从 std::ostream 派生的其他类来执行此操作。
要重定向标准输出,您需要重新打开文件句柄。 此帖子有一些这种性质的想法。
You could do something like this with cout or cerr:
Or, you can do that with a
std::stringstream
or some other class derived fromstd::ostream
.To redirect stdout, you'd need to reopen the file handle. This thread has some ideas of this nature.
这就是我要做的:
This is what I'd do:
在这里,我们将设置一个新的入口点
consoleMain
来覆盖您自己的入口点。defaultMain
。在源代码中的某个位置声明原始入口点(以便我们可以链接到它)和新入口点。 两者都必须声明
extern "C"
以防止名称损坏。<前><代码>外部“C”
{
int defaultMain (void);
int consoleMain(无效);
}
实现入口点功能。
将测试代码添加到某处,例如在按钮单击操作中。
consoleMain
设置为新入口点(项目属性/链接器/高级/入口点)。Here we'll set a new entry point
consoleMain
that overrides your own one.defaultMain
.Somewhere in your source code declare the original entry point (so we can chain to it) and the new entry point. Both must be declared
extern "C"
to prevent name mangling.Implement the entry point function.
Add your test code somewhere, e.g. in a button click action.
consoleMain
as the new entry point (Project Properties/Linker/Advanced/Entry Point).感谢 greyfade 答案中的 gamedev 链接,我能够编写并测试这段简单的代码,
它可以工作并且足以进行调试。 将文本放入更具吸引力的 GUI 元素需要更多的工作。
Thanks to the gamedev link in the answer by greyfade, I was able to write and test this simple piece of code
It works and is adequate for debugging. Getting the text into a more attractive GUI element would take a bit more work.