Frage

Ich bin Geschenkpapier vorhandenen C++ - code aus einem BSD Projekt in unserer eigenen benutzerdefinierten wrapper und ich möchten zu integrieren, um unseren code mit so wenig änderungen wie möglich.Dieser code verwendet fprintf drucken stderr um zu loggen und melden Sie Fehler.

Ich möchte leiten Sie diese an einem alternativen Ort innerhalb des gleichen Prozesses.Auf Unix Ich habe dies getan, mit einem socketpair und eine thread:ein Ende der Buchse ist, wo ich senden stderr (über einen Aufruf von dup2) und das andere Ende ist überwacht in einem thread, wo ich kann dann den Ausgang.

Dies funktioniert nicht auf Windows wenn da ein sockel ist nicht das gleiche wie ein Datei-handle.

Alle Dokumente, die ich gefunden habe, auf der web-show, wie man umleiten der Ausgabe von einem untergeordneten Prozess, das ist nicht was ich will.Wie kann ich umleiten stderr innerhalb des gleichen Prozesses immer ein Rückruf von einer Art, wenn die Ausgabe geschrieben wird?(und bevor Sie sagen, ich habe versucht SetStdHandle aber finde keine Möglichkeit diese Arbeit zu machen)...

War es hilfreich?

Lösung

Sie verwenden können eine ähnliche Technik auf Windows, Sie nur verwenden müssen, um verschiedene Wörter für die gleichen Konzepte.:) Dieser Artikel: http://msdn.microsoft.com/en-us/library/ms682499.aspx verwendet eine win32-pipe-handle-I/O von einem anderen Prozess, Sie müssen nur tun die gleiche Sache mit threads innerhalb des gleichen Prozesses.Natürlich, in Ihrem Fall alle Ausgaben auf stderr aus, die irgendwo in dem Prozess, werden umgeleitet zu Ihrem Verbraucher.

Tatsächlich, die anderen Teile des Puzzles, die Sie möglicherweise benötigen, sind _fdopen und _open_osfhandle.In der Tat, hier ist ein Verwandtes Beispiel aus einigen code Ich veröffentlichte vor Jahren:

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;
}   

In diesem Fall wird der Hauptprozess war ein GUI-Prozess beginnt nicht mit stdio Griffe an alle.Es öffnet sich eine Konsole, dann schiebt die richtigen Griffe in stdout und stdin, so dass der debug () - Funktion (die wurde als eine stdio-interaktive Funktion) interagieren kann, mit der neu geschaffenen Konsole.Sie sollten in der Lage sein zu öffnen, einige Pfeifen und machen die gleiche Art von Sache zum umleiten von stderr.

Andere Tipps

Sie haben sich daran zu erinnern, dass das, was MSVCRT Anrufe "OS-Griffe" sind nicht Win32-Griffe, aber eine andere Ebene der Griffe Hinzugefügt, nur um Sie zu verwirren.MSVCRT versucht zu emulieren, die Unix-handle-Nummern, wo stdin = 0, stdout = 1, stderr = 2 und so weiter.Win32-Griffe sind anders nummeriert und Ihre Werte immer geschehen, zu sein ein Vielfaches von 4.Öffnen Sie das Rohr und bekommen Sie alle Handgriffe richtig konfiguriert wird, benötigen immer Ihre Hände unordentlich.Über die MSVCRT-source-code und ein debugger ist wahrscheinlich eine Voraussetzung.

Sie erwähnen, dass Sie nicht wollen, um eine named pipe für die interne Verwendung;lohnt es sich wahrscheinlich, poining heraus, dass die Unterlagen für CreatePipe() Staaten, "Anonyme pipes implementiert sind über eine named pipe mit einem eindeutigen Namen.Daher können Sie oft ein handle übergeben, um eine anonyme pipe zum einen die Funktion, die erfordert, dass Sie einen Griff, um eine named pipe." Also, ich schlage vor, dass Sie nur eine Funktion schreiben, die schafft eine ähnlich Rohr mit den richtigen Einstellungen für den asynchronen Lesen.Ich Neige dazu, verwenden Sie eine GUID als string (generiert mit CoCreateGUID() und StringFromIID()), um mir einen eindeutigen Namen erstellen und dann die server und client enden der named pipe mit den richtigen Einstellungen für überlappende I/O (mehr details über diese, und code, hier: http://www.lenholgate.com/blog/2008/02/process-management-using-jobs-on-windows.html).

Einmal habe ich, dass ich Draht bis einige code, den ich zum Lesen einer Datei mit overlapped I/O mit einem I/O Completion Port und, gut, dann bekomme ich nur async-Benachrichtigungen der Daten, wie es ankommt...Jedoch, ich haben eine Menge von gut getesteten code für die Bibliothek gibt, macht es alles möglich...

Es ist wahrscheinlich möglich, das named pipe-und dann eben ein überlappendes Lesen, die mit einem Ereignis in Ihrem OVERLAPPED Struktur und prüfen Sie das Ereignis zu sehen, ob Daten verfügbar war...Ich habe keinen code zur Verfügung, dass bedeutet, dass, obwohl.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top