2016-04-18 10 views
0

Ich habe diese Funktion geerbt, die ich aus meinem Code aufrufen muss. Die Funktion ist von einer Bizzare-Bibliothek in einer arkanen Programmiersprache - also kann ich nicht annehmen, fast alles darüber, abgesehen von der Tatsache, dass es einige nützliche Informationen zu stdout druckt.In-Memory-Datei zum Abfangen von stdout bei Funktionsaufruf

Lassen Sie mich ihre Wirkung simulieren mit

void black_box(int n) 
{ 
    for(int i=0; i<n; i++) std::cout << "x"; 
    std::cout << "\n"; 
} 

Ich möchte das Zeug abfangen und verwenden es ausgibt. Zu diesem Zweck ich stdout in eine temporäre Datei umleiten, rufen Sie die black_box, dann die stdout wiederherzustellen und die Sachen aus der temporären Datei lesen:

#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <unistd.h> 

#include <iostream> 


int main(void){ 
    int fd = open("outbuff", O_RDWR | O_TRUNC | O_CREAT, 0600); 

    // Redirect stdout to fd 
    int tmp = dup(1); 
    dup2(fd, 1); 

     // Execute 
     black_box(100); 
     std::cout << std::flush; 

    // Restore old stdout 
    dup2(tmp, 1); 

    // Read output from the outbuff flie 
    struct stat st; 
    fstat(fd, &st); 
    std::string buf; 
    buf.resize(st.st_size); 

    lseek(fd, 0, SEEK_SET); 
    read(fd, &buf[0], st.st_size); 
    close(fd); 

    std::cout << "Captured: " << buf << "\n"; 

    return 0; 
} 

Dies funktioniert. Aber das Erstellen einer Datei auf der Festplatte für solch eine Aufgabe ist nicht etwas, das ich stolz bin. Kann ich etwas wie eine Datei machen, aber im Speicher?

Bevor Sie eine Pipe vorschlagen, beachten Sie bitte, was passieren würde, wenn black_box seinen Puffer überläuft. Und nein, ich brauche es single-threaded - starten einen zusätzlichen Prozess/Thread besiegt den ganzen Zweck, was ich versuche zu erreichen.

Antwort

1

Ich möchte abfangen und die Sachen verwenden, die es ausgibt.

[...] Bitte beachten Sie, was passiert, wenn black_box seinen Puffer überläuft.

Ich sehe zwei Alternativen.

  1. Wenn Sie die maximale Größe der Ausgabe erkennen, und die Größe ist nicht zu groß, verwenden Sie die socketpair statt pipe. Im Gegensatz zu Pipes können Sockets die Größe der Egress/Ingress-Puffer ändern.

  2. Verwenden Sie eine temporäre Datei unter /tmp. Im Normalfall wird die Festplatte nicht berührt (außer das System tauscht). Zu diesem Zweck gibt es wenige Funktionen, zum Beispiel mkstemp (oder tmpfile).