Hallo an alle C# Spezialisten Ich habe gerade begonnen meine VB6 Applikationen auf C# umzustellen bzw. neu zu machen. Ich versuche verzweifelt folgendes VB6 Construkt halbwegs vernünftig auf C# zu implementieren. Global L as Object In der MainForm gibts eine Listbox "ListBox1" Im "Load Event" der Mainform steht Set L=ListBox1 Und nun kann ich applikationsübergreifend mit z.B. L.Additem auf die Listbox zugreifen. Ohne daß ich allen Forms oder Klassen in denen ich die Listbox verwenden will eine Instanzkopie der MainForm übergebe und über eine Zusätzliche Funktion dann auf diese Kopien zugreife, und in der MainForm für alle diese Klassen oder Forms in welchen ich die Listbox verwenden will mit "new" Instanzen erzeuge, bringe ich das nicht zustande. Gibt es keine einfachere Möglichkeit, da kommt ja für die einfachsten Dinge eine Menge CodeMuell zusammen. Viele Grüsse Peter
Ohoh, so viele Probleme auf einmal ;-) 1. Globale Objekte = böse. Nicht verwenden! 2. Zugriff auf Steuerelement nicht von überall her machen, sondern NUR AUS DEM GUI Thread. Sonst gibts Exceptions. 3. Wenn du von anderswo auf die Steuerelemente einer anderen Form zugreifen willst, hast du ein Architekturproblem. Denn sowas sollte man eigentlich niemals tun wollen/müssen. => Kannst du etwas genauer beschreiben was du vorhast (vor allem WARUM du das so machen willst)? Ich vermute es gibt einen ganz einfachen Ansatz, der alle deine Probleme löst...
Hallo Quizbart, Danke für Deine Antwort. Ich weiss, daß die Archetektur von VB Programmen nicht zu der von einer sehr rigiden Objektorientierung passt. Aber ich möchte halt nicht alles neu erfinden. Bei den Applikationen handelt es sich um diverse Kommunikationsserver, die das Bindeglied zwischen Visualiserungssystemen und Echtzeitsystemen wie z.B. einer SPS oder einem MC darstellen. Da geht es um DDE-Kommunikatin, serielle Schnittstellen, CAN-Bus, Profibus etc. Die Programme sind funktions- und nicht oberflächenmodular aufgebaut, und jedes Funktionsmodul greift auf ein zentrales Anzeigemodul (MainForm) zu. Ich habe inzwischen auch schon eine Variante mit "Events" im Testbetrieb am laufen. Aber das ist auch eher aufwendig. In den enzellnen Modulen muß man die Events feuern und in der Mainform sind dann unzählige Callbackprozeduren zu kodieren. Ich habe auch versucht in C# in der Mainform eine public Prozedur zu definieren, die von den Modulen die Informationen bekommt, und diese dann in eine die Listbox schreibt. Aber mir gelingt es nicht von aus einer anderen Klasse diese Prozedur in der Mainform auftzurufen. Aber wahrscheinlich bin ich noch nicht fit genug in C# Gruß Peter
Hmmm... Ich werde dir jetzt mal nicht mit MVP-Pattern und Dergleichen kommen ;-) Wenn du es wirklich quick und dirty machen willst, lass deine MainForm einfach für alles was du brauchst entsprechende Methoden anbieten (z.B. AddItemToMyList, SetMylabelText usw.). In den methoden erledigst du dann das Update des Steuerelements (Invoke nicht vergessen!).
Ja Danke Ich hab inzwischen eine Möglichkeit gefunden die C# Gurus würden mich wahrscheinlich dafür lynchen. Im program.cs public static MainForm MeineMainForm=null MeineMainForm = new MainForm(); Application.Run(MeineMainForm); Im MainForm.Designer Die gewünschen Objekte oder Funktionen auf public setzen Und schon kann man von überall mit Program.MeineMainForm..... zugreifen. Gruß Peter
Peter schrieb: > die C# Gurus würden mich wahrscheinlich dafür lynchen. Und die C++,Java,ruby,Scala,Python, etc. etc. Leute... Wenn man eine stark OOP-fokussierte Sprache wie C# verwenden will sollte man bereit sein ein Minimum an Zeit darin zu investieren, die OOP-Grundprinzipien zu lernen... Und ja, der typische Weg ist es, alle Objekte überall immer zu übergeben, anstelle sie als globale Varialbe zu setzen. So bedeutet es keinen großen Umbau-Aufwand, wenn man sich in Zukunft dazu entscheidet doch mal zwei Fenster anzeigen zu wollen o.ä.
Hallo Kindergärtner, Ja Du hast ja im Prinzip recht. Es ist halt wie überall so, daß manche Dinge objektorientiert und andere prozedural einfacher zu lösen sind. Manchmal habe ich halt das Gefühl, daß diese rigide Objektorientierung etwas übertrieben ist. So wie z.B. beim Borland C, da kann man wie man will mischen, und einen sehr effizienten und lesbaren Code erzeugen - aber leider ist das Zeugs etwas teuer. Ebenfalls ist das VB6 gut gegangen, nur läufts schon ab Win7/64 nicht mehr stabil. Viel Grüsse Ein leidgeplagter C# Einsteiger
Peter schrieb: > Es ist halt wie überall so, daß manche Dinge objektorientiert und > andere prozedural einfacher zu lösen sind. 99,9% der komplexeren Programme profitieren, von Objektorientierung und ganz besonders GUI-Programme, erst recht wenn sie mehrere Fenster haben und dann noch aus mehreren Systemen bestehen. > Manchmal habe ich halt das Gefühl, daß diese rigide Objektorientierung > etwas übertrieben ist. Bei ganz einfachen kleinen Programmen, vielleicht. > So wie z.B. beim Borland C, da kann man wie man will mischen Im Borland C kann man objektorientiert programmieren? Oha. Mischen kann man in vielen OOP-Sprachen auch, wie C++, ruby, java, Scala. > und einen sehr effizienten und lesbaren Code erzeugen - aber leider ist > das Zeugs etwas teuer. OOP hat zum Glück nichts mit Effizienz zu tun, man kann mit & ohne OOP effizienten und ineffizienten Code produzieren. Bei komplexen Programmen wird nicht-OOP-Code gerne mal schnell unlesbar und schwer zu durchschauen. In deinem Beispiel ist alles über diese globale Variable verknüpft, und man kann diese Verbindung nicht einfach umstellen. Freie C,C++ -Compiler gibt es übrigens auch für Windows.
Kindergärtner schrieb: > Und ja, der typische Weg ist es, alle Objekte überall immer > zu übergeben, anstelle sie als globale Varialbe zu setzen. Wenn man ganz hipp sein will: per Dependency-Injection bzw. mit einem IOC-Container kann man sich auch das sparen!
Ja ich meinte ja C++ von Borland Kindergärtner hat ja recht, es ist eh geil 100% OO zu programmieren, aber es artet halt gerne in Codierungsonanie aus, und ist alles andere als wirtschaftlich, wenn man nicht Monsterprogramme als Massenware entwickelt. Wo gibts einen vernünftigen freien C++ Compiler, nur einmal zu schauen ob's etwas taugt, für schnelle, kostensparende Programmentwicklung ? Gott sei Dank sind die Meinunge verschieden, damit ist die Vielfalt in Technik und Wissenschaft gewährleistet. Liebe Grüsse Peter
Das geht ganz einfach und ohne nachzudenken: In VisualStudio soll es ein Tool geben, das von VB6 nach VB.net übersetzt. Einen Übersetzer von VB.net nach C# gibt es hier: http://www.developerfusion.com/tools/convert/vb-to-csharp/ Oder hier: http://codeconverter.sharpdevelop.net/SnippetConverter.aspx Fertig! Zumindest in der Theorie. Probier's doch einfach mal aus und berichte, wie es funktioniert hat :)
Hi Yalu X. Danke für Deine Hinweise. Den Konverter von VB Net haben wir schon getestet. Funktioniert nur sehr selten. Bei etwas aufwendigeren Projekten (eingebundene OCX, fremde DLL's, DDE etc.) ist neu schreiben schneller und sicherer. Vielelicht kannst Du etwas empfehlen, was halbwegs zukunftsicher (so für 5-8 Jahre) ist. Für unsere Zwecke ist Bedienoberfläche und GUI nachrangig. Es geht hauptsächlich darum schnell und effizient vor Ort (bei laufenden Maschinen und Anlagen) Kommunikationskanäle zu belauschen und Kommunikationsprotokolle zu analysieren. Wie das Programm aussieht ist völlig wurscht, das Ergebnis ist wichtig. Wir nennen das bei uns "PROBIERGRAMMIEREN". VB6 war hier optimal. Borland C++ ist auch nicht schlecht, ist aber teuer, und muß für jeden Rechner lizensiert werden, und das geht nur per Internet. Gruß Peter
Peter schrieb: > Vielelicht kannst Du etwas empfehlen, was halbwegs zukunftsicher (so für > 5-8 Jahre) ist. Für unsere Zwecke ist Bedienoberfläche und GUI > nachrangig. C#/.NET ist da schon voll OK. Das einzige was sich von Zeit zu Zeit mal ändert sind die GUI Frameworks. Wenn du aber entsprechend designst (z.B. MVP) kannst du die einfach austauschen, falls es mal nötig sein sollte. Dann läuft's sogar auf dem Mac oder Linux ;-) Aber ich denke nicht, dass WinForms in den nächsten Jahren aussterben wird, also bist du mit deinem momentanen Ansatz schon auf der sicheren Seite...
Peter schrieb: > Ja ich meinte ja C++ von Borland Sag das doch?! > Kindergärtner hat ja recht, es ist eh geil 100% OO zu programmieren, > aber > es artet halt gerne in Codierungsonanie aus, Am Anfang, ja > und ist alles andere als > wirtschaftlich Falls richtig umgesetzt, wird es ab ca. der 1442.ten zeile sehr wirtschaftlich, da man sich viel fummelige Wartungsarbeit und durchforsten von verkorkstem prozeduralen Code erstpart. > wenn man nicht Monsterprogramme als Massenware > entwickelt. Auch Einzelanfertigungen kann man "richtig" entwickeln. > Wo gibts einen vernünftigen freien C++ Compiler, nur einmal zu schauen > ob's > etwas taugt, für schnelle, kostensparende Programmentwicklung ? Die bekanntesten: MinGW: http://mingw.org http://mingw-w64.sourceforge.net/ Cygwin: http://www.cygwin.com/ Microsoft Visual C++ Express: http://www.microsoft.com/visualstudio/deu/downloads#d-2010-express Gibt aber bestimmt noch hundert andere. > Gott sei Dank sind die Meinunge verschieden, damit ist die Vielfalt in > Technik und Wissenschaft gewährleistet. Weise ;-)
Boris B. schrieb: > Wenn man ganz hipp sein will: per Dependency-Injection bzw. mit einem > IOC-Container kann man sich auch das sparen! Dann reicht man halt einen Container herum, das machts jetzt nicht viel sparsamer :)
Kindergärtner schrieb: > Dann reicht man halt einen Container herum, das machts jetzt nicht viel > sparsamer :) Nenene, der Container wird NICHT herumgereicht. das ist ja das schöne dran. Die Abhängigkeiten werden alle automatisch aufgelöst, ohne dass man den IOC-Container danach fragen muss. Und wenn du doch mal dynamische Objekte brauchst kannst du dir eine entsprechende Factory injezieren lassen, und die Objekte dann darüber erzeugen lassen.
Boris B. schrieb: > Nenene, der Container wird NICHT herumgereicht. Ah, wie kommt man denn dann an den Container? Packt man den in eine globale Variable? Und was macht man wenn man mehrere Hauptfenster hat, von denen jedes ein Unterfenster hat, und man vom Unterfenster das Hauptfenster haben möchte? Die getMainWindow Methode einer globalen IoC-Container-Instanz wüsste ja gar nicht welches Hauptfenster es sein soll. Boris B. schrieb: > Die Abhängigkeiten werden alle automatisch aufgelöst, ohne dass > man den IOC-Container danach fragen muss. Und wie komme ich dann im Unterfenster an das Hauptfenster?
Dr. Sommer schrieb: > Ah, wie kommt man denn dann an den Container? Garnicht. Der Container erzeugt dich, also muss er dich kennen, du aber ihn nicht. Dr. Sommer schrieb: > Und wie komme ich dann im Unterfenster an das Hauptfenster? Das hat mit IOC nichts zu tun. Hier würde das Hauptfenster sich selber beim Erzeugen der Unterfenster z.B. per Konstruktor an dieses Übergeben (natürlich nur in Form eines Interfaces). Dr. Sommer schrieb: > Packt man den in eine > globale Variable? Globale Variablen gibt's in C# nicht ;-)
Peter schrieb: > Den Konverter von VB Net haben wir schon getestet. > > Funktioniert nur sehr selten. War das die Konvertierung von VB6 nach VB.Net, die Schwierigkeiten gemacht hat oder die von VB.Net nach C#? Letztere sollte eigentlich recht leicht vonstatten gehen, da VB.Net und C# semantisch ja praktisch die gleiche Sprache sind und sich im Wesentlichen nur im syntaktischen Zucker unterscheiden. Zwischen VB6 und VB.Net ist allerdings – anders als es die ähnlichen Namen vermuten lassen – der Unterschied schon sehr deutlich. > Vielelicht kannst Du etwas empfehlen, was halbwegs zukunftsicher (so für > 5-8 Jahre) ist. Für unsere Zwecke ist Bedienoberfläche und GUI > nachrangig. Es ist ganz schwer vorauszusagen, was in 5-8 Jahren noch aktuell sein wird. Ein paar der Urgesteine wie C werden garantiert immer noch einen hohen "Marktanteil" haben, ein paar der moderneren Sprachen werden schon wieder ausgestorben sein. Bei Sprachen wie VB.Net und C#, die im Wesentlichen von einer einzelnen Softwarefirma getragen werden, ist die Gefahr naturgemäß größer, dass irgendwann der Support eingestellt wird (bei VB Classic ist dies ja schon passiert). Nahezu unsterblich werden nur diejenigen Sprachen werden, deren Anwenderkreis eine kritische Masse überschreitet, wie dies bspw. bei C, C++ und Java der Fall ist. Die Schwelle zu dieser kritischen Masse liegt aber recht hoch und ist bei C# noch lange nicht erreicht. > VB6 war hier optimal. Kann man VB6 eigentlich nicht mehr benutzen? Der Support ist ja schon seit längerem eingestellt worden, aber das heißt ja nicht unbedingt, dass es für die "PROBIERGRAMMIERUNG" nicht mehr gut genug wäre.
Boris B. schrieb: > Hier würde das Hauptfenster sich selber > beim Erzeugen der Unterfenster z.B. per Konstruktor an dieses Übergeben > (natürlich nur in Form eines Interfaces). Genau das meinte ich mit dem herumreichen in meinem 1. Post. Über das Interface kann man sich streiten. Mehr braucht man gar nicht... Boris B. schrieb: > Globale Variablen gibt's in C# nicht ;-) Auch keine funktions/Klassen-statischen (wie in Java, C++)? Die sind ja quasi global.
Kindergärtner schrieb: > Genau das meinte ich mit dem herumreichen in meinem 1. Post. Über das > Interface kann man sich streiten. Mehr braucht man gar nicht... OK, dann sind wir uns ja einig. Da kommt man halt nicht drum herum. Über die Interfaces sollte man allerdings nicht streiten müssen. Wenn du hier direkt die Klasse verwendest, erzeugst du eine starke Kopplung zwischen deinen beiden Klassen, die dann später die Wartung erschwert und z.B. Unit Tests unmöglich macht. Kindergärtner schrieb: > Auch keine funktions/Klassen-statischen (wie in Java, C++)? Die sind ja > quasi global. Statische Klassen kannst du natürlich schon als globale Variablen misbrauchen (die dunkle Seite der Macht...).
Boris B. schrieb: > OK, dann sind wir uns ja einig. Oh gut ;) Boris B. schrieb: > Wenn du > hier direkt die Klasse verwendest, erzeugst du eine starke Kopplung > zwischen deinen beiden Klassen, die dann später die Wartung erschwert > und z.B. Unit Tests unmöglich macht. Ich weiß, aber irgendwo ist dann auch overkill. Da die beteiligten Klassen alle GUI-Fenster darstellen die sich gegenseitig steuern ist es auch unwahrscheinlich dass er ein einzelnes davon in einen Unit-Test packt und das andere als Mock aufsetzt... Aber was hier sauberer ist ist natürlich klar. Boris B. schrieb: > Statische Klassen kannst du natürlich schon als globale Variablen > misbrauchen (die dunkle Seite der Macht...). Na kommt drauf an, ein paar wenige Sachen gibts immer, die einfach nur global Sinn machen.
Kindergärtner schrieb: > Na kommt drauf an, ein paar wenige Sachen gibts immer, die einfach nur > global Sinn machen. Aber auch da könnte man den IOC-Container schön einsetzen. Jede Klasse, die auf globale Einstellungen zugreifen muss, bekommt z.B. ein IGlobalOptions-Interface in den Konstruktor. In der Konfiguration des IOC-Containers gibt man dann an, dass dieses Interface als Singleton aufgelöst werden soll. Und voila, schon haben beliebeige Klassen zugriff auf die "globalen variablen", ohne dass man tatsächlich eine benutzt hätte. Und mocken lässt sich das Ganze dann nachher auch wunderbar. Aber naja, je nach Projektgröße ist so ein Rum-ge-pattere natürlich tatsächlich Overkill. Dann wollen wir mal den Thread nicht weiter zuspammen ;-)
Boris B. schrieb: > Aber auch da könnte man den IOC-Container schön einsetzen. Können kann man immer... ;-) > Und mocken lässt sich das Ganze dann nachher auch wunderbar. Was wenn die globale Variable einfach nur das Programm-Icon ist, die global ist damit alle 1000 Einzelfenster des Programms direkt drauf zugreifen können? Die braucht man auch nicht zu mocken, und wenn man das Icon ändern will ändert man onehin die Datei... Gilt auch für andere Arten von "Caches" deren Sinn es gerade ist, dass man sie nur 1x von der Platte laden muss, o.ä. Boris B. schrieb: > Dann wollen wir mal den Thread nicht weiter zuspammen ;-) ach dazu sind wir doch in einem Forum ;)
Kindergärtner schrieb: > ach dazu sind wir doch in einem Forum ;) Ja dann :-D Kindergärtner schrieb: > Was wenn die globale Variable einfach nur das Programm-Icon ist, die > global ist damit alle 1000 Einzelfenster des Programms direkt drauf > zugreifen können? Man will doch nicht sämtliche Resourcen über den gesamten Lebenszyklus des Programms im Speicher haben. Hier würde man doch besser einen Resourcen-Manager implementieren, der auf Anfrage die Icons rausrückt (und z.B. durch Lazy-Initialization nur die Grafiken lädt, die wirklich gebraucht werden). Und an den Resourcen-Manager kommen die Objekte dann natürlich per IOC-Container ;-) Noch hast du mich also nicht von der Notwendigkeit von globalen variablen überzeugt...
Die Konvertierung von VB6 auf NET geht schon meistens nicht. Wenn ich die Beiträge hier lese komme ich aus dem Staunen nicht raus. Welcher Container welches Unterfenster nicht mehr kennt und auf welchen Thread er dann beleidigt ist, dem kann ich nicht mehr folgen. Ich hab Gott sei Dank immer nur einfachere Probleme. wie z.B. Auslesen einer Recordstruktur aus einer Binärdatei [VB6] Type BEAMSETtype INFO(6) As String * 256 HORIZONTAL(5, 1023) As Byte VERTIKAL(5, 1023) As Byte ORDER(16) As String * 43 End Type Dim BEAMSET as BEAMSETtype On Error Resume FILEREADERROR_HANDLER Open "20051213.BMS" For Random As #1 Len = Len(BEAMSET) Get #1, RecIdx, BEAMSET Close #1 Ich Google mir schon einen Wolf um einige Hinweise für eine vernünftige Lösung in C# zu finden. Ich scheitere schon an der struct mit fixer Länge. Ich fürchte ich muß die Records, deren Länge und deren Positionen ja bekannt sind, mit BinaryRead in ein Bytearray lesen, und dann den Datensatz per pedes zusammenstöpseln. Liebe Grüsse Peter
Boris B. schrieb: > Man will doch nicht sämtliche Resourcen über den gesamten Lebenszyklus > des Programms im Speicher haben. > Hier würde man doch besser einen Resourcen-Manager implementieren, der > auf Anfrage die Icons rausrückt (und z.B. durch Lazy-Initialization nur > die Grafiken lädt, die wirklich gebraucht werden). Es sei denn es handelt sich um ein gewöhnliches GUI-Programm, dann werden die Icons genau so lange gebraucht wie das Programm läuft = wie >= 1 Fenster offen ist... > Und an den Resourcen-Manager kommen die Objekte dann natürlich per > IOC-Container ;-) Dann muss man aber dafür sorgen dass nur max 1 Instanz existiert. > Noch hast du mich also nicht von der Notwendigkeit von globalen > variablen überzeugt... Notwendig ist gar nichts, nur manchmal sind die Alternativen einfach maximaler Overkill.
> Notwendig ist gar nichts, nur manchmal sind die Alternativen einfach > maximaler Overkill. Aus meiner Seele gesprochen !!!!
Jetzt erklärt dem Peter doch mal, wie man in C# Records aus einer Binärdatei liest. Ich selber weiß leider nur, wie das in C[++] geht.
Yalu X. schrieb: > Jetzt erklärt dem Peter doch mal, wie man in C# Records aus einer > Binärdatei liest. Ich selber weiß leider nur, wie das in C[++] geht. Solche Details interessieren uns nicht, vor allem wenn man sich viel trefflicher tolle IoC und DI-Techniken überlegen kann! Im Ernst, keine Ahnung wie das in C# geht, in C++ wüsst ichs (denn da ists trivial) ;-)
Kindergärtner schrieb: > Dann muss man aber dafür sorgen dass nur max 1 Instanz existiert. Das ist ohne Weiteres möglich: in der Konfiguration des IOC-Containers lässt sich sowas festlegen. Zudem: Irgendwo musst du ja auch das Icon laden und in der Variablen ablegen. Also brauchst du sowieso einen Resourcen-Manager, der das übernimmt. Damit liegen unsere Ansätze also doch recht nah beieinander... @Topic: Sowas hier? http://www.dotnetperls.com/binaryreader
Boris B. schrieb: > Das ist ohne Weiteres möglich: in der Konfiguration des IOC-Containers > lässt sich sowas festlegen. Ja, oder man nimmt eine globale Variable, das ist dan dasselbe. > Zudem: Irgendwo musst du ja auch das Icon laden und in der Variablen > ablegen. Also brauchst du sowieso einen Resourcen-Manager, der das > übernimmt. Nö:
1 | Image appIcon { PREFIX "/myapp/icon.png" }; |
2 | |
3 | MyMainWindow::MyMainWindow () { |
4 | setIcon (appIcon); |
5 | }
|
Wobei PREFIX aus der config.h und ./configure kommt.
Yalu X. schrieb: > Die Schwelle zu dieser kritischen Masse liegt aber recht hoch und ist bei > C# noch lange nicht erreicht. Mono unter Linux ist leider auch nur c# syntaxkompatibel, das .net-Zeug nicht. Sehr ärgerlich...
Yalu X. schrieb: > Jetzt erklärt dem Peter doch mal, wie man in C# Records aus einer > Binärdatei liest. Ich selber weiß leider nur, wie das in C[++] geht. Ja in [C++] ists fast genau so einfach wie in VB In C# gehts schon gar nicht auf dem geraden Weg in einem struct einen String mit fester Länge zu definieren, sogar ein ByteArry ist nicht die Anzahl der Bytes lang sondern doppelt so lange. Einige Leute sollten sich vielleicht auf ein Bier treffen, um die akademischen Diskussionen fortzuführen, und nicht den Thread überladen. Das würde vielleicht die zwischenmenschlichen Beziehungen fördern - oder - könnte es vielleicht auch in Agressionen ausarten ! Peter der Grosse
Peter schrieb: > Ja in [C++] ists fast genau so einfach wie in VB Du kannst C++? Warum machst du das Ganze dann nicht damit? Man hört immer wieder, dass man mit C# besonders einfach GUIs erstellen kann. Ich kann auch mir gut vorstellen, dass das tatsächlich so ist, aber Peter schrieb: > Für unsere Zwecke ist Bedienoberfläche und GUI nachrangig. Ganz abgesehen kann man ja auch in C++ GUIs entwickeln, und bis zum Erscheinen von .NET & Co hat sich auch kaum einer beschwert, dass das nur mit großem Aufwand ginge. Peter schrieb: > Vielelicht kannst Du etwas empfehlen, was halbwegs zukunftsicher (so für > 5-8 Jahre) ist. Mit C++ hast du immerhin eine Sprache, die mit ziemlicher Sicherheit die nächsten 8 Jahre überleben wird, selbst dann, wenn Windows bis dahin gestorben sein sollte.
Yalu X. schrieb: > Mit C++ hast du immerhin eine Sprache, die mit ziemlicher Sicherheit die > nächsten 8 Jahre überleben wird, selbst dann, wenn Windows bis dahin > gestorben sein sollte. Ich hab ein wenig was in [C++] aber von Borland für eine befreundete Firma gemacht, und habe ganz auf OOP verzichtet. Das braucht kein .NET macht eine EXE-Datei die kannst Du überall hin kopieren und es läuft. Ist aber sehr teuer - einige 1000€ Ich trau michs hier ja gar nicht sagen - ich komme von der MC Seite, und fühle mich bei Assembler und Ansi-C am wohlsten. Da weiß ich bei jedem Befehl was genau im proc abgeht. Das C++ von MS ist der gleiche "Sch.." wie das C# Glaubst Du, daß die .NET basierenden Systeme zukunftsicher sind ? Ich habe meine Rechner jetzt schon zugemüllt mit .NET von 1 - 4.5 weil viele Programme verschiedene .NET Versionen benötigen. Ein Java-Fuzzy hat mir den Umstieg auf C# angeraten. Java ist ja noch schlimmer, da mutiert man vor lauter Tipperei zur Sekretärin. Aber was solls, da muß ich eben durch. Aber offenbar kann oder will mir tatsächlich niemend einen Tipp geben, wie mein obig skizziertes Beispiel in C# vernünftig zu handeln ist. Danke für Deine Info's Gruß Peter
Kindergärtner schrieb: > Yalu X. schrieb: >> Jetzt erklärt dem Peter doch mal, wie man in C# Records aus einer >> Binärdatei liest. Ich selber weiß leider nur, wie das in C[++] geht. > Im Ernst, keine Ahnung wie das in C# geht, in C++ wüsst ichs (denn da > ists trivial) ;-) Trivial, aber vom Compiler, der Zielarchitektur etc. abhängig... Ansonsten ist das in C#/VB nicht wirklich komplizierter
1 | [StructLayout(LayoutKind.Explicit, Pack = 1)] |
2 | public struct TestXYZ { |
3 | [FieldOffset(3)] |
4 | public UInt32 testUInt32; |
5 | [FieldOffset(42)] |
6 | public double testDouble64; |
7 | }
|
8 | |
9 | T ByteArrayToStruct<T>(byte[] input) { |
10 | GCHandle handle = GCHandle.Alloc(input, GCHandleType.Pinned); |
11 | T result = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); |
12 | handle.Free(); |
13 | return result; |
14 | }
|
15 | |
16 | var input = File.ReadAllBytes("filename"); |
17 | var result = ByteArrayToStruct<TestXYZ>(input); |
man könnte aber auch alles einzeln mit http://msdn.microsoft.com/library/System.IO.BinaryReader.aspx einlesen
Arc Net schrieb: > Kindergärtner schrieb: >> Yalu X. schrieb: >>> Jetzt erklärt dem Peter doch mal, wie man in C# Records aus einer >>> Binärdatei liest. Ich selber weiß leider nur, wie das in C[++] geht. >> Im Ernst, keine Ahnung wie das in C# geht, in C++ wüsst ichs (denn da >> ists trivial) ;-) > > Trivial, aber vom Compiler, der Zielarchitektur etc. abhängig... > Ansonsten ist das in C#/VB nicht wirklich > komplizierter[StructLayout(LayoutKind.Explicit, Pack = 1)] > public struct TestXYZ { > [FieldOffset(3)] > public UInt32 testUInt32; > [FieldOffset(42)] > public double testDouble64; > } > > T ByteArrayToStruct<T>(byte[] input) { > GCHandle handle = GCHandle.Alloc(input, GCHandleType.Pinned); > T result = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), > typeof(T)); > handle.Free(); > return result; > } > > var input = File.ReadAllBytes("filename"); > var result = ByteArrayToStruct<TestXYZ>(input); > man könnte aber auch alles einzeln mit > http://msdn.microsoft.com/library/System.IO.Binary... einlesen Danke für Deine Mühe Mein CSharp kann mit den "T ByteArr...." und "T result" nichts anfangen. Der möchte immer nach den T's einen ";" machen. Aber ich werd's morgen noch einmal versuchen P.S.: Mit einem Eindim. Bytearray und BinaryRead funktionierts problemlos, ist mir aber zuwider es so zu machen, Dein Vorschlag gefällt mir besser. Gruß Peter
Peter schrieb: > Ich hab ein wenig was in [C++] aber von Borland für eine befreundete > Firma gemacht, und habe ganz auf OOP verzichtet. Das ist ja für kleinere Anwendungen und "Probiergrammieren" völlig in Ordnung. > Das braucht kein .NET macht eine EXE-Datei die kannst Du überall hin > kopieren > und es läuft. > Ist aber sehr teuer - einige 1000€ Bei C++ gibt es ja nicht nur einen Compiler. Magst du den einen nicht, dann nimm einfach den nächsten. Der GCC kostet nichts, und der MS-Compiler ist m.W. ebenfalls umsonst. > Ich trau michs hier ja gar nicht sagen - ich komme von der MC Seite, und > fühle mich bei Assembler und Ansi-C am wohlsten. Da weiß ich bei jedem > Befehl was genau im proc abgeht. Es ist dir freigestellt, auch auf dem PC in Assembler zu programmieren, die Tools dafür gibt es gratis und open-source. Du kannst aber auch C (mit GCC) oder C-like in C++ programmieren, ganz wie es dir am besten gefällt. > Das C++ von MS ist der gleiche "Sch.." wie das C# Wieso das? Das ist doch ganz normales C++ wie auch beim Borland-Compiler oder GCC. Du solltest dich nur von C++/CLI fernhalten. Das enthält zwar "C++" im Namen, ist aber eine .NET-Sprache und hat mit dem klassischen C++ nur einen Teil der Syntax gemeinsam. Ansonsten kannst du dir ja auch mal Code::Blocks anschauen. Ich selber verwende es nicht, es gibt aber (auch hier im Forum) viele positive Meinungen dazu: www.codeblocks.org Das ist eine C++-IDE, die mit mehreren unterschiedlichen Compilern, darunter GCC, MSVC und Borland-C++ zusammenarbeitet. > Glaubst Du, daß die .NET basierenden Systeme zukunftsicher sind ? Ein paar Jahre wird es .NET mindestens noch geben, da MS einen nicht unerheblichen Entwicklungsaufwand hineingesteckt hat. Wahrscheinlich wird es sich sogar solange halten können, wie es klassische PCs gibt, und die werden auch nicht von heute auf morgen verschwinden. Aber sicher die Zukunft vorhersagen kann niemand. > Ein Java-Fuzzy hat mir den Umstieg auf C# angeraten. Ja klar. Und jeder C#-Fuzzy wird dir von Java abraten. Das ist wie Windows und Linux :) Arc Net schrieb: > [StructLayout(LayoutKind.Explicit, Pack = 1)] > public struct TestXYZ { > [FieldOffset(3)] > public UInt32 testUInt32; > [FieldOffset(42)] > public double testDouble64; > } Diese benutzerdefinierbaren Struct-Layouts sind eine coole Sache. Ich hätte so etwas niemals in einer stark abstrahierenden Sprache wie C#, sondern eher in einer "Nerd Edition" von C erwartet, weil man damit sicher auch extrem viel Unfug treiben kann :)
Peter schrieb: > Mein CSharp kann mit den "T ByteArr...." und "T result" nichts anfangen. > Der möchte immer nach den T's einen ";" machen. > Aber ich werd's morgen noch einmal versuchen C# kennt Generics eigentlich ab der Version 2.0 Yalu X. schrieb: > Diese benutzerdefinierbaren Struct-Layouts sind eine coole Sache. Ich > hätte so etwas niemals in einer stark abstrahierenden Sprache wie C#, > sondern eher in einer "Nerd Edition" von C erwartet, weil man damit > sicher auch extrem viel Unfug treiben kann :) Dann halt die "Nerd Hardcore Edition": Ada... http://en.wikibooks.org/wiki/Ada_Programming/Attributes/%27Bit_Order#Example http://en.wikibooks.org/wiki/Ada_Programming/Attributes/%27Size http://www.sigada.org/ada_letters/sept2005/Endian-Independent%20Paper.pdf
Yalu X. schrieb: > sondern eher in einer "Nerd Edition" von C erwartet Also dem ganz normalen C99? Bitfields schonmal von gehört?
Kindergärtner schrieb: > Also dem ganz normalen C99? Bitfields schonmal von gehört? Wenn ich die Structs mit LayoutKind.Explicit richtig verstanden habe, haben sie mit den Bitfields von C wenig bis gar nichts zu tun. Diese sind ja auch nicht besonders nerdig, sondern einfach auf Bitebene gepackte Integers in einer Struktur. In den C# ist es aber bspw. möglich, Struct-Elemente teilweise überlappen zu lassen, wie es in folgendem Programm geschieht:
1 | using System; |
2 | using System.Runtime.InteropServices; |
3 | |
4 | [StructLayout(LayoutKind.Explicit)] |
5 | public struct MyStruct { |
6 | [FieldOffset(0)] public uint i1; |
7 | [FieldOffset(1)] public uint i2; |
8 | }
|
9 | |
10 | public class CSharpApp { |
11 | static void Main() { |
12 | MyStruct m; |
13 | |
14 | m.i1 = 0x12345678; |
15 | System.Console.WriteLine("m.i1 = {0:X}", m.i1); |
16 | |
17 | m.i2 = 0x9abcdef0; |
18 | System.Console.WriteLine("m.i2 = {0:X}", m.i2); |
19 | System.Console.WriteLine("m.i1 = {0:X}", m.i1); |
20 | }
|
21 | }
|
Dabei überlappen sich m.i1 und m.i2 in 3 Bytes, wodurch "interessante" Überschreibungseffekte möglich sind. Die Ausgabe ist
1 | m.i1 = 12345678 |
2 | m.i2 = 9ABCDEF0 |
3 | m.i1 = BCDEF078 |
Die C#-Structs sind somit eine Verallgemeinerung der Structs und Unions in C. Gibt man keine FieldOffsets an, erhält ein ein gewöhnliches Struct. Schreibt man vor jedes Element "FieldOffset(0)", erhält man eine Union. Benutzt man aber FieldOffset mit beliebigen Argumenten (wie im obigen Beispiel), kann man damit die verrücktesten Sachen zaubern. In C kann man durch den Missbrauch von Pointer-Arithmetik und -Casts ähnliche Dinge anstellen, aber da hebt der Standard sofort den Finger und sagt "undefined". In C# hingegen scheint ein solches Vorgehen durch den Standard nicht nur erlaubt, sondern sogar unterstützt zu werden. Deswegen: C# == Nerd-Sprache :D
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.