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
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.orghttp://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.
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
ImageappIcon{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
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 :)
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
usingSystem;
2
usingSystem.Runtime.InteropServices;
3
4
[StructLayout(LayoutKind.Explicit)]
5
publicstructMyStruct{
6
[FieldOffset(0)]publicuinti1;
7
[FieldOffset(1)]publicuinti2;
8
}
9
10
publicclassCSharpApp{
11
staticvoidMain(){
12
MyStructm;
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