Windows C++: ¿Cómo puedo redireccionar stderr para llamadas a fprintf?




stdout stderr (2)

Estoy envolviendo el código C ++ existente de un proyecto BSD en nuestro propio contenedor personalizado y quiero integrarlo a nuestro código con el menor número de cambios posible. Este código usa fprintf para imprimir en stderr con el fin de registrar / informar errores.

Quiero redirigir esto a un lugar alternativo dentro del mismo proceso. En Unix he hecho esto con un par de socket y un hilo: un extremo del socket es donde envío stderr (a través de una llamada a dup2 ) y el otro extremo se supervisa en un hilo, donde luego puedo procesar la salida.

Sin embargo, esto no funciona en Windows porque un socket no es lo mismo que un manejador de archivo.

Todos los documentos que he encontrado en la web muestran cómo redirigir el resultado de un proceso secundario, que no es lo que quiero. ¿Cómo puedo redireccionar stderr dentro del mismo proceso obteniendo una devolución de llamada de algún tipo cuando se escribe la salida? (Y antes de decirlo, he probado SetStdHandle pero no puedo encontrar ninguna forma de hacer que esto funcione) ...

https://code.i-harness.com


Puede usar una técnica similar en Windows, solo necesita usar palabras diferentes para los mismos conceptos. :) Este artículo: http://msdn.microsoft.com/en-us/library/ms682499.aspx utiliza un conducto win32 para manejar las E / S de otro proceso, solo tiene que hacer lo mismo con los hilos dentro del mismo proceso. Por supuesto, en su caso, toda la salida a stderr desde cualquier lugar del proceso se redireccionará a su consumidor.

En realidad, otras piezas del rompecabezas que puede necesitar son _fdopen y _open_osfhandle . De hecho, aquí hay un ejemplo relacionado de algún código que publiqué hace años:

DWORD CALLBACK DoDebugThread(void *)
{
    AllocConsole();
    SetConsoleTitle("Copilot Debugger");
    // The following is a really disgusting hack to make stdin and stdout attach
    // to the newly created console using the MSVC++ libraries. I hope other
    // operating systems don't need this kind of kludge.. :)
    stdout->_file = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);
    stdin->_file  = _open_osfhandle((long)GetStdHandle(STD_INPUT_HANDLE), _O_TEXT);
    debug();
    stdout->_file = -1;
    stdin->_file  = -1;
    FreeConsole();
    CPU_run();
    return 0;
}   

En este caso, el proceso principal fue un proceso de GUI que no comienza con stdio maneja en absoluto. Abre una consola, luego coloca las manijas derechas en stdout y stdin para que la función debug (), que fue diseñada como una función interactiva stdio, pueda interactuar con la consola recién creada. Debería poder abrir algunas tuberías y hacer el mismo tipo de cosas para redirigir a stderr.


Debe recordar que lo que MSVCRT llama "controladores OS" no son identificadores Win32, sino que se agrega otra capa de identificadores para confundirlo. MSVCRT intenta emular los números de control de Unix donde stdin = 0, stdout = 1, stderr = 2 y así sucesivamente. Los identificadores Win32 están numerados de forma diferente y sus valores siempre son múltiplos de 4. Abrir el conducto y configurar todos los controladores configurados correctamente requerirá que las manos se ensucien. Usar el código fuente de MSVCRT y un depurador es probablemente un requisito.





redirect