FILE* auf Hauptspeicher
-
Hallo,
ich verwende eine Bibliothek, welche ihre Eingabe als FILE*-Handles bekommen möchte. Ich würde allerdings gerne einen String übergeben. Daher wäre es gut, wenn ich einen FILE-Handle auf einen Zeiger im Hauptspeicher erstellen könnte? Ist das in C möglich? Oder braucht man dafür eventuell platform invokes? Wenn ja, welche WinAPI kann mir weiterhelfen (und bitte Thread verschieben)?
-
Ich weiß jetzt nicht genau, in welche Richtung Deine Frage geht...
#include <io.h> #include <stdio.h> void Load(char *filename) { FILE *fp; int handle; int filelen; if ((fp = fopen(filename, "rb")) == 0) return; handle = fileno(fp); filelen = filelength(handle); /* ... */ fclose(fp); }
-
probier mal das:
#include <stdio.h> #include <windows.h> #include <io.h> #include <fcntl.h> FILE *CreateMemoryFileFromString (char *str) { HANDLE in, out; DWORD written; // pipe anlegen und was reinschreiben CreatePipe (&in, &out, NULL, 0); WriteFile (out, str, strlen(str), &written, 0); CloseHandle (out); // win32 handle in FILE* umwandeln return _fdopen (_open_osfhandle ((long)in, O_RDONLY), "r"); } void main() { FILE *fp = CreateMemoryFileFromString ("toll, was?\n"); // file ausgeben while (!feof(fp)) putchar (fgetc (fp)); // ende fclose (fp); }
-
Hi ten,
Spot-on.
Danke für die Lösung, passt perfekt.
-
Hallo,
leider reicht das für meine Bedürfnisse doch nicht ganz aus, ich muss nämlich nicht nur aus der Datei lesen sondern auch reinschreiben können. Ist es möglich, analog auch eine Datei zum Lesen und Schreiben zu erhalten? Ich habe es nicht hinbekommen. Leider ist Microsofts Dokumentation dieser Funktionen auch nicht besonders gut. Mein Problem ist, dass ich keinen Weg finde, die zwei Handles der Pipe in *einen* für die Datei zu konvertieren bzw. wenigstens zwei Datei-Handles (einen für Lesen und einen für Schreiben) zu bekommen.
-
Konrad Rudolph schrieb:
...wenigstens zwei Datei-Handles (einen für Lesen und einen für Schreiben) zu bekommen.
void CreateMemoryFile (FILE **read, FILE **write) { HANDLE in, out; CreatePipe (&in, &out, NULL, 0); *read = _fdopen (_open_osfhandle ((long)in, O_RDONLY), "r"); *write = _fdopen (_open_osfhandle ((long)out, O_WRONLY), "w"); } void main() { FILE *read; FILE *write; CreateMemoryFile (&read, &write); fputs ("hello world\n", write); fflush (write); while (!feof(read)) putchar (fgetc (read)); fclose (read); fclose (write); }
hätteste aber selber leicht drauf kommen können
btw: für ein handle das r/w kann, könnt's mit 'sections' gehen.
guckst du: http://msdn2.microsoft.com/en-us/library/aa366537.aspx
-
Vielen Dank.
ten schrieb:
hätteste aber selber leicht drauf kommen können
Ja. Irgendwie habe ich mich beim Ausprobieren verrannt und hatte angenommen, dass nach dem Aufruf von _open_osfhandle mit einem Handle auch der *andere* Handle nicht mehr gültig war (CloseHandle lieferte einen Fehler).
-
Hallo,
es gibt noch ein Problem. Und zwar hängt Dein Code, wenn ich ihn genauso übernehme. Und zwar wird folgende Schleife anscheinend nie verlassen:
while (!feof(read)) putchar (fgetc (read));
Und zwar scheint er kein EOF zu erkennen sondern liest weiter, wobei sich 'fgetc' in ein Deadlock begibt. Woran liegt das bzw. wie verhindert man das?
-
Ich habe unter Windows noch nie mit Pipes gearbeitet, aber zumindest unter UNIX musst Du das schreibende Ende schließen, damit das lesende ein EOF anzeigt. Denn so weiss die API ja nicht dass Du nicht später noch etwas in die Pipe schreiben würdest.
-
Hi,
LordJaxom schrieb:
Ich habe unter Windows noch nie mit Pipes gearbeitet, aber zumindest unter UNIX musst Du das schreibende Ende schließen, damit das lesende ein EOF anzeigt. Denn so weiss die API ja nicht dass Du nicht später noch etwas in die Pipe schreiben würdest.
Hmm, klingt nicht unlogisch und führt auch zu Resultaten. Aber wie machen denn das die Standardpipes? Ich meine, STDIN kann ja auch gelesen werden, ohne dass das andere Ende STDOUT geschlossen hat.
In meinem Fall ist es nunmal wichtig, dass ich kontinuierlich lesen und schreiben kann.
/EDIT: Na ja gut, ich kann erstmal mit zwei unterschiedlichen Streams arbeiten, auch wenn's unkomfortabel ist. Danke euch auf jeden Fall.
-
stdin und stdout sind ja auch zwei unabhängige Streams. Sozusagen ist ersterer der Eingabe-Stream auf "Tastatur" und zweiterer der Ausgabestream auf "Konsole" (auch wenn beides durch die Konsole kontrolliert wird). Bei einer Pipe geht ja das was auf der Schreibseite reingeht auf der Leseseite wieder raus.
Analogie Pipes in der Konsole: Wenn Du etwas wie "type x.txt | more" machst, ist stdout von type mit stdin von more als Pipe verbunden. more bekommt auch erst dann EOF, wenn type stdout schließt (hier implizit durch Programmende).
-
Da der Thread leider von einem extrem agressiven Spambot befallen wurde, mache ich den mal dicht. Falls es noch Fragen zum Thema gibt, bitte einen neuen Thread aufmachen und auf diesen verweisen. Danke.