2010-11-25 55 views
2

我使用C++创建了一个win32控制台应用程序。我使用了一些API(不是我的,我不能修改它的源代码)。它的写法是,它将一些信息写到控制台屏幕上,而不是每次我调用它时(每秒48次)所以我想把它放到某个线程中并限制它的输出能力,但是我需要得到当该线程将尝试输出一些对我来说很重要的消息时通知。我有标准字符串中的消息文本。如何使用boost在C++中做这样的事情?Boost:如何创建一个线程,以便您可以控制其所有标准输出,标准错误?

回答

1

该功能在Boost中不存在。你可以,但是,使用_dup2来代替标准输出描述:

#include <cstddef> 
#include <cstdio> 
#include <cstdlib> 
#include <io.h> 
#include <iostream> 
#include <windows.h> 

int main() 
{ 
    HANDLE h = CreateFile(TEXT("test.txt"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
    if (0 == SetStdHandle(STD_OUTPUT_HANDLE, h)) { 
     std::fprintf(stderr, "`SetStdHandle` failed with error %d\n", (int)GetLastError()); 
     return EXIT_FAILURE; 
    } 

    int h_desc = _open_osfhandle((long)h, 0); 
    _dup2(h_desc, STDOUT_FILENO); 

    std::printf("test\r\n"); // This actually writes to `h`. 
    std::fflush(stdout); 

    std::cout << "another test" << std::endl; // Also writes to `h` 

    CloseHandle(h); 
    return EXIT_SUCCESS; 
} 

本质上讲这招的确是让你所有的写操作重定向到stdoutstd::coutGetStdHandle(STD_OUTPUT_HANDLE)到您选择的一个可写的句柄(h) 。当然,您可以使用CreatePipe来创建可写句柄(h)并从另一个线程的可读端读取。

编辑:如果你正在寻找一个跨平台解决方案,请注意,这一招是POSIX兼容的系统更容易,因为dup2unistd.h的标准功能和“可写的处理”都已经描述符。

1

我不能想出一种方法来实现提升你想要的东西,因为描述了问题。

但是,这个API行为非常令人困惑。向控制台吐出大量输出是有点反社会的。您是否使用API​​库的Debug版本?您确定没有办法配置API,以便将此数据输出到不同的流,以便您可以在不捕获整个标准输出的情况下对其进行过滤?有没有办法减少输出量,这样你只能看到你关心的重要事件?

如果您确实需要捕获标准输出并对某些感兴趣的字符串(事件)执行操作,那么Win32提供了这样做的方法,但我真的很想看看是否可以修改此输出来满足您的要求在诉诸这些之前需要。

2

这里有一个疯狂的想法:如果LIB使用COUT/CERR

,你可以用自己的实现来替代这些全局变量的流缓冲。它将在flush/data上检查一些线程局部变量,以查看数据是否来自调用该库的线程,然后将其路由到其他地方(即转换为std :: string/std :: ostringstream)而不是常规的cout/cerr streambufs。 (你应该保持在这个范围内。)

如果它使用c的stdout/stderr,我认为这样做很难做到正确,但它仍然可行。您需要创建一些管道并来回路由。更多的是C/unixy问题,那我现在还不太了解......。 :)

希望它有帮助。

相关问题