print fprintf c++ windows redirect

c++ - fprintf - print in stderr c



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

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.

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) ...


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.


Usted menciona que no desea utilizar un conducto con nombre para uso interno; Probablemente valga la pena señalar que la documentación para CreatePipe () dice: "Las canalizaciones anónimas se implementan utilizando un canal específico con un nombre único. Por lo tanto, a menudo se puede pasar un identificador a un canal anónimo a una función que requiere un identificador para un nombre tubo." Por lo tanto, sugiero que solo escriba una función que cree un conducto similar con la configuración correcta para la lectura asíncrona. Tiendo a usar un GUID como una cadena (generada usando CoCreateGUID() y StringFromIID() ) para darme un nombre único y luego crear los extremos del servidor y el cliente de la tubería con nombre con la configuración correcta para E / S superpuesto (más detalles sobre esto, y el código, aquí: http://www.lenholgate.com/blog/2008/02/process-management-using-jobs-on-windows.html ).

Una vez que tengo eso, conecto un código que tengo que leer un archivo usando E / S superpuesto con un puerto de finalización de E / S y, bueno, solo recibo notificaciones asincrónicas de los datos a medida que llegan ... Sin embargo, Tengo una buena cantidad de código de la biblioteca bien probado que hace que todo suceda ...

Probablemente sea posible configurar la tubería con nombre y luego hacer una lectura superpuesta con un evento en su estructura OVERLAPPED y verificar el evento para ver si los datos estaban disponibles ... No tengo ningún código disponible que haga eso.