Hallo, ich habe ein C-Programm was mir laufen 3 Werte in einer Textdatei aktualisiert, alle 10ms, 100ms würde auch noch reichen. Außerdem habe ich ein C#-Programm, was diese Daten alle 100ms ausliest. Leider gibts einen Fehler. Das statische Lesen und Schreiben funktioniert, nur nicht das parallele. Hat da jemand eine Lösung dafür? Bzw. welche andere Möglichkeit zum Datenaustausch zwischen den beiden Programmen besteht? Lg
> Leider gibts einen Fehler. Irgendeinen? ;-) > Das statische Lesen und Schreiben funktioniert, nur nicht das parallele. Mit welchen Funktionen? read() und write()? Wenn dein OS POSIX-konform ist, findest du entsprechende Informationen im POSIX Programmer's Manual. Zitat aus der write-Dokumention: After a write() to a regular file has successfully returned: * Any successful read() from each byte position in the file that was modified by that write shall return the data specified by the write() for that position until such byte positions are again modified. * Any subsequent successful write() to the same byte position in the file shall overwrite that file data. Du kannst davon ausgehen, dass sich in POSIX eine Datei aus der Sicht von read() und write() wie ein großes, dynamisches Byte-Array verhält. Wenn ein Byte erfolgreich mit write geschrieben worden ist, kann es auch mit read wieder gelesen werden, selbst dann, wenn sich die Daten noch in einem Puffer des OS bzw. des Dateisystems befinden und noch nicht auf die Festplatte geschrieben worden sind. Etwas anders verhält es sich, wenn das Anwendungsprogramm eine (zusätz- liche) eigene Pufferung vornimmt (bspw. in den Funktionen fprintf, fwrite usw.). Dann funktioniert die Sache zwar immer noch, die Daten können aber beim OS und damit beim Empfänger verzögert ankommen, je nach Pufferstrategie. Im Linux Programmer's Manual steht noch der Hinweis: POSIX requires that a read(2) which can be proved to occur after a write() has returned returns the new data. Note that not all file systems are POSIX conforming. Wenn du also ein anders OS als Unix/Linux benutzt, brauchst du also nur in der Dokumentation des OS und des verwendeten Dateisystems nachzu- schlagen, ob ausreichende POSIX-Konformität besteht, oder ob es ver- gleichbare Alternativkonstrukte gibt. Selbst das Windows-API erhebt den Anspruch, in großen Teilen POSIX- konform zu sein. Es besteht also durchaus die Chance, dass der "Fehler" nicht durch Windows, sondern von dir selbst verursacht wird. Anmerkung zum Schluss: In Unix/Linux macht bspw. der Befehl tail -f von der Möglichkeit des simultanen Schreibens und Lesens durch zwei unterschiedliche Prozesse Gebrauch, was auch problemlos funktioniert. Es kann also kein schlechter Stil sein, so zu verfahren ;-)
yalu, de OP schreibt was von C#. Das schließt *nix zwar lang nicht aus, macht es doch aber recht unwahrscheinlich. Spätestens der Unwille Pipes (hail to the allmighty pipe!) zu verwenden, bestätigt das.
Tom schrieb: > yalu, de OP schreibt was von C#. Das schließt *nix zwar lang nicht > aus, macht es doch aber recht unwahrscheinlich. Ich habe zwar ebenfalls vermutet, dass es um Windows geht, war mir aber nicht 100% sicher. Deswegen habe ich mit den OSen angefangen, von denen ich weiß, daß das Unterfangen realisierbar ist, und zusätzlich einen Hinweis darauf gegeben, dass es unter Windows evtl. genauso geht. Ich habe aber gerade keinen Rechner zum Testen hier und keinen Nerv, in der Loseblattsammlung names MSDN¹ zu wühlen ;-) ¹) MSDN ist doch die offizielle Windows-Dokumentation, oder gibt es vielleicht noch eine etwas strukturiertere?
gleichzeitig lesen und schreiben in einer Datei, ist zwar möglich aber nicht sehr sinnvoll. Warum musst du denn das machen? Brauchst du die Daten wirklich in der Datei oder hast du dir bloss den weg überlegt um die Daten von C nach C# zubekommen?
Regelmeister
> Sieht recht kompliziert aus, gibt es eine einfachere Methode?
Du meine Güte, nimm halt Pipes. Dateien zur Inter-Prozess-Kommunikation
zu verwenden ist doch tiefstes Mittelalter!
Ja ihr habt mich überzeugt, ich werds mit Pipes versuchen... muss da nur schauen wie es jeweils geht in c und c#.
Die ursprüngliche Methode geht auch zur Not... Beispiel:
1 | // C-Teil, schreiben, Win-API
|
2 | HANDLE h = CreateFile(fileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); |
3 | |
4 | while (true) { |
5 | WriteFile(h, buffer, bufferLen, &written, NULL); |
6 | }
|
7 | |
8 | // C#-Teil, lesen
|
9 | var file = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); |
10 | var sr = new StreamReader(file, System.Text.Encoding.ASCII); |
11 | var line = sr.ReadLine(); |
Soweit bin ich:
1 | hPipe = CreateNamedPipe("\\.\pipe\mypipe",PIPE_ACCESS_DUPLEX,FILE_FLAG_OVERLAPPED,2,10,10,0,NULL); |
2 | while(ConnectNamedPipe(hPipe,NULL)==0){ |
3 | }
|
4 | printf("Pipe-client connected!\n"); |
Das ist der Code in C, der folgende in C#:
1 | private void button3_Click(object sender, EventArgs e) |
2 | {
|
3 | NamedPipeClientStream anypipe = new NamedPipeClientStream("mypipe"); |
4 | anypipe.Connect(); |
5 | }
|
Leider wird das printf nicht ausgegeben. Der obere Code wird zuerst gestartet.
Du nimmst den Rückgabewert von ConnectNamedPipe() nur, um in eine Endlosschleife zu gehen, falls es nicht klappt. Die Doku sagt dazu:
1 | If the operation is synchronous, ConnectNamedPipe does not return |
2 | until the operation has completed. If the function succeeds, the |
3 | return value is nonzero. If the function fails, the return value |
4 | is zero. To get extended error information, call GetLastError. |
Hol doch mal den Fehler, vielleicht ist der ja aufschlußreich?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.