Windows C++: Comment puis-je rediriger stderr pour les appels à fprintf?
Je suis d'emballage existantes du code C++ à partir d'un BSD projet dans notre propre enveloppe et je veux l'intégrer à notre code avec aussi peu de changements que possible. Ce code utilise fprintf
à imprimer à stderr afin de log /rapport d'erreurs.
Je veux rediriger vers un autre lieu dans le même processus. Sur Unix je l'ai fait avec un socketpair
et un thread
: une extrémité de la douille est là que j'ai envoyer stderr (via un appel à dup2
) et l'autre extrémité est surveillé dans un fil de discussion où je peux ensuite le processus de la sortie.
Cela ne fonctionne pas sur Windows mais parce que le socket n'est pas le même comme un descripteur de fichier.
Tous les documents que j'ai trouvé sur le web montrent comment rediriger la sortie d'un processus enfant, ce qui n'est pas ce que je veux. Comment puis-je rediriger stderr dans le même processus d'obtention d'un rappel de la sorte, lorsque la sortie est écrite? (et avant de vous le dire, j'ai essayé SetStdHandle
mais ne peut pas trouver un moyen de faire fonctionner)...
OriginalL'auteur jkp | 2008-08-11
Vous devez vous connecter pour publier un commentaire.
Vous pouvez utiliser une technique similaire sur Windows, vous avez juste besoin d'utiliser des mots différents pour désigner les mêmes concepts. 🙂 Cet article: http://msdn.microsoft.com/en-us/library/ms682499.aspx utilise un win32 pipe pour gérer les I/O à partir d'un autre processus, il vous suffit de faire la même chose avec les threads du même processus. Bien sûr, dans votre cas, toutes les sorties vers stderr à partir de n'importe où dans le processus serez redirigé vers votre consommateur.
En fait, d'autres pièces du puzzle, vous pourriez avoir besoin sont _fdopen et _open_osfhandle. En fait, voici un exemple similaire de certains code je l'ai publié, il y a des années:
Dans ce cas, le processus principal est une interface graphique de processus qui ne démarre pas avec stdio gère tout. Il ouvre une console, puis lui enfonce la poignée droite dans stdin, stdout, et donc la fonction debug () (qui a été conçu comme un stdio fonction interactive) peuvent interagir avec le nouvellement créé de la console. Vous devriez être capable d'ouvrir certains tuyaux et faire le même genre de chose pour rediriger stderr.
OriginalL'auteur Greg Hewgill
Vous devez vous rappeler que ce MSVCRT appelle "l'OS gère" ne sont pas Win32 poignées, mais une autre couche de poignées ajouté juste pour vous confondre. MSVCRT essaie d'émuler les Unix gérer les numéros où
stdin
= 0,stdout
= 1,stderr
= 2 et ainsi de suite. Win32 poignées sont numérotées différemment et de leurs valeurs de toujours arriver à être un multiple de 4. L'ouverture du canal et de l'obtention de toutes les poignées correctement configuré nécessitera de se salir les mains. À l'aide de la MSVCRT code source et un débogueur est probablement une exigence.OriginalL'auteur Greg Hewgill
Vous mentionnez que vous ne souhaitez pas utiliser un tube nommé, à usage interne, il est probablement utile de poining que la documentation de CreatePipe() unis, "Anonyme tuyaux sont mis en œuvre à l'aide d'un tube nommé avec un nom unique. Par conséquent, vous pouvez passer souvent d'une poignée pour un canal anonyme à une fonction qui nécessite un handle vers un canal nommé." Donc, je suggère que vous venez d'écrire une fonction qui crée une semblable conduite avec les paramètres corrects pour async lecture. J'ai tendance à utiliser un GUID comme une chaîne de caractères (générées à l'aide
CoCreateGUID()
etStringFromIID()
) pour me donner un nom unique, puis de créer le serveur et le client extrémités du tube nommé avec les paramètres corrects pour overlapped I/O (plus de détails sur ce, et le code, ici: http://www.lenholgate.com/blog/2008/02/process-management-using-jobs-on-windows.html).Une fois que j'ai que j'ai des fils du code que je dois lire un fichier à l'aide de overlapped I/O avec un I/O Port d'Achèvement et, bien, alors je viens d'obtenir async notifications des données qu'il arrive... Cependant, j'ai une bonne quantité de bien testé le code de la bibliothèque qui fait tout ce qui se passe...
Il est probablement possible de paramétrer le canal nommé et puis il suffit de faire un chevauchent lire avec un événement dans votre
OVERLAPPED
de la structure et de la vérification de l'événement pour voir si les données sont disponibles... je n'ai pas de code qui le fait bien.OriginalL'auteur Len Holgate