2017-01-25 1 views
2

Wie kann ich ein C++ streambuf -Objekt von einem C FILE * erhalten, so dass es den Puffer des FILE-Objekts verwendet und vermeidet, dass beide Objekte separate Puffer verwalten, während sie auf dieselbe zugrunde liegende Datei verweisen.Wie erstellt man ein C++ streambuf-Objekt aus einer C FILE *, teilt seinen Puffer (und Pufferzustand) mit dem FILE-Objekt, auf das gezeigt wird?

Es sieht so aus, als ob es keine Standardmethode dafür gibt.

Boost verfügt über eine stream_buffer-Klasse mit einem Konstruktor, der einen Dateideskriptor verwendet, wodurch die Verwendung von C++ - Funktionen in einer mit C-Code geöffneten Datei ermöglicht wird. Zum Beispiel:

boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_sink> mysb (fileno(myFileptr), boost::iostreams::never_close_handle)); 

myFileptr vom Typ FILE *. Das Problem ist, dass mysb und das FILE-Objekt, auf das von myFileptr gezeigt wird, getrennte Puffer verwalten, so dass dies keine Option ist ...

Hier ist der Kontext meines Problems. Ich muss eine dynamisch verknüpfbare Bibliothek mit einer C-Schnittstelle bereitstellen (alle exportierten Variablen, Funktionsargumente und Funktionsrückgabewerte müssen C-Typen haben), aber die Bibliothek wird tatsächlich in C++ entwickelt.

Wenn ich eine Funktion exportieren, intern unter Verwendung von C++ Stream Einrichtungen, mit diesem Prototyp

Void MyExportedFunct(FILE* myfile) 

Und ich die Bibliothek in einem C-Programm importieren:

int main() 
{ 
    FILE * fptr = fopen(“SomeFile”, "w"); 
    fprintf(fptr, “Some data.”) 
    MyExportedFunct(fptr); 
    fprintf(fptr, “Some more data…”) 
    return 0; 
} 

ich die Daten möchte in die Datei geschrieben werden, die tatsächlich in der richtigen Reihenfolge gesendet wird (Vermeidung von verschachtelten Zeichen).

Jeder Vorschlag, wie dies zu erreichen ist oder für einen anderen Ansatz, ist willkommen.

+0

Typografische Anführungszeichen wie '„somefile“' show Dies ist nicht der eigentliche Code. Es tut uns leid, das C-Tag zu entfernen und wiederherzustellen. –

+0

@ WeatherVane Ich bin mir nicht sicher, dass Sie falsch lagen. Dies ist definitiv eine Frage zu C++, die Tatsache, dass es Einrichtungen verwendet, die von C geerbt wurden, sollte nicht relevant sein. –

+0

@MarkRansom Ich wurde vor kurzem zum Entfernen eines C-Tags hingelegt, als C in der Frage erwähnt wurde. Hier importiert OP die Bibliothek in ein C-Programm. –

Antwort

3

Es gibt einen C++ - Streambuf, der keine Ebene ist und nach der Referenz sucht. Das ist eine Ebene über dem stdio, dann würde es ausreichen, den Strompuffer konstant zu leeren.

Die automatische bündiger Teil wird dadurch erreicht, portably std::unitbuf mit:

mysb << std::unitbuf; 

Ahh, es stdio_filebuf genannt und kommt mit C gcC++ Bibliothek: __gnu_cxx::stdio_filebuf::stdio_filebuf constructor

+0

Wie @ ben-voigt darauf hinweist, ist dies eine gcc-Erweiterung. Es gibt keinen tragbaren Weg, dies zu tun. –

+2

@MarshallClow: Das ist bedauerlich, weil die Standard-Bibliothek unbedingt erforderlich ist, um 'streambuf'-Klassen zu erstellen, die über' FILE * 'liegen, um das richtige' sync_with_stdio() '-Verhalten für' cin', 'cout',' zu erhalten cerr 'und' clog'.Diese Klassen werden nicht standardmäßig für die Verwendung mit anderen Dateien/Streams verfügbar gemacht. –

+0

@BenVoigt: Wenn das C 'FILE'-Objekt und das' stdio_filebuf'-Objekt denselben zugrunde liegenden Puffer gemeinsam haben, müssen sie nicht ständig gelöscht werden. Recht? – Guett31

Verwandte Themen