Hallo ich bin absoluter beginer in C#!
drum möchte ich mich schon mal endschuldigen !!!
Also zu meiner Frage ich habe einen Mikrokontroller der sendet eine
structur Byte für Byte über die Uart raus indem ich der Sende Functio
einfach start und stop Adresse übergebe ! Nun Möchte ich diese Daten auf
der selben Art und weise wieder Empfangen und mit den Unterschiedlichen
Daten im Programm Arbeiten ! Da ich aber nicht weis wie ich anfangen
soll hoffe ich von Euch etwas hilfe zu bekommen !!
Danke schon mal
Gruß
Pier
Hi Pier,
du brauchst dich nicht zu entschuldigen, dass du Anfänger bist. Besser
wärs, sich dafür zu entschuldigen, dass du keine konkreten Informationen
lieferst.
Wie sieht deine Struktur im µC aus? Das Prinzip ist allgemein gesehen
einfach:
- im µC Daten aus Struktur lesen und senden
- in C# empfangen und an entsprechende Stelle in der Struktur schreiben.
Mit der Antwort kannst du wahrscheinlich soviel anfangen wie ich mit der
Frage. Du musst schon sagen, wo genau es klemmt...
Ralf
Also ich hab zum Beispiel eine solche Structur
struct
{
unsigned char start;
unsigned char adres ;
unsigned char comando;
int eine_nummer;
unsigned char chksum;
unsigned char ende;
} Comout;
Um diese zu senden übergeb ich meiner Sende Function den poiter auf den
Anfang und Ende Dieser Daten !
Da es aber in C# anscheinend keine Poiter giebt weis ich nicht wie ich
diese Daten wieder so empangen kann ???
Danke ich hoffe ich konnte mich jetzt klarer ausdrücken !!
Gruß
PIER
Pier S. wrote:
> Da es aber in C# anscheinend keine Poiter giebt weis ich nicht wie ich> diese Daten wieder so empangen kann ???
Nein, Poiter gibt's in C# keine!
Wenn's nicht anders geht, kannst Du ja byteweise empfangen und selber
konvertieren. Dabei kannst Du, wenn nötig, auch Single-Byte Characters
in Unicode konvertieren, resp. den int korrekt konvertieren (Grösse des
Int, Endian).
Zwei Punkte:
1. Wenn es eine festgelegte Struktur ist, kann man mit Attributen die
exakte Anordnung der Strukturinhalte festlegen
(von der ungünstigen Strukturgröße und der ungünstigen Anordnung mal
abgesehen)
1
usingSystem.Runtime.InteropServices;
2
3
[StructLayout(LayoutKind.Explicit,Size=9)]
4
structComOut1{
5
[FieldOffset(0)]
6
bytestart;
7
[FieldOffset(1)]
8
byteadres;
9
[FieldOffset(2)]
10
bytecommando;
11
[FieldOffset(3)]
12
inteine_nummer;
13
[FieldOffset(7)]// falls int ein 32-Bit Integer ist
14
unsignedcharchksum;
15
[FieldOffset(8)]
16
unsignedcharende;
17
}
18
19
// oder
20
21
[StructLayout(LayoutKind.Sequential,Pack=1)]
22
structComOut2{
23
bytestart;
24
byteadres;
25
bytecommando;
26
inteine_nummer;
27
unsignedcharchksum;
28
unsignedcharende;
29
}
der "schwierigere" Teil:
Entweder man macht die gesamte Anwendung unsafe und castet/kopiert wie
in C/C++ oder man benutzt die saubereren Möglichkeiten.
1. BinaryReader (dann braucht man das StructLayout nicht mehr)
2. Marshal.StructureToPtr / Marshal.PtrToStructure
Das ganze mischt dann fröhlich managed und unmanaged Speicher, erfordert
das manuelle freigeben/anfordern des Speichers (Marshal.AllocHGlobal (
Marshal.FreeHGlobal)
3. Will man das in 1. vorgeschlagene auch wartungsfreundlich gestalten,
landet man bei Reflection/Emit.
Arc Net Danke für deine Hilfe ,wenn ich auch sagen muß Bahnhof !!
Aber ich schau mir das alles mal an , hab jetzt ja Stichworte mit denen
ich suchen kann !
Die ganze Sache ist wesentlich schwiriger als ich am Anfang gedacht habe
!!
Beim Komunizieren zwischen zwei MC ging meine Methode sehr gut da ich
ganz gleich welchen Daten Typ ich auch versendet oder emfangen habe
immer nur nach jedem Byte meinen Zeiger um Eins erhöhen musste !!
Sollte jemand ein Beispiel haben ( C#) wäre ich sehr dankbar!!
Gruß
Pier
Warum legst du in C# nicht einfach ein Array an, in dem du die Daten
ablegst. Wenn alle Daten da sind, machst du die entsprechende Zuweisung
vom Array in deine Struktur.
Ralf
weil sowas in C# nicht geht... C# ist eine Hochsprache und mag es nicht
wenn man irgendwelche Annahmen macht wie die Daten im Speicher liegen.
Die Lösung mit dem BinaryReader ist sauber und einfach, man darf sich
als hardwarenaher C oder Assembler Programmierer nur nicht Gedanken
machen das alles doch irgendwie performanter gehen müsste.
Wenn man weiss wie, kann man Dein Problem in C# ganz einfach lösen.
Wie schon beschrieben wurde, musst Du erst mal das Struct in C#
ebenfalls mit einem Struct oder einer Klasse nachbilden.
Danach kannst Du mit sogenannten serializern, deserializern den
Datenstrom ganz einfach einlesen oder ausgeben. Alles managed, ohne
Pointer und Basteleien.
Such mal im Netz weitere Informationen zum Serialisieren und melde Dich
wieder, falls Du nicht weiterkommst.
Also was man normalerweise und standardmässig in einem solchen Fall
machen würde, ist das ganze Ding in ein Unsigned Char Array einzulesen
und das ganze Array einfach zu einer Structur Casten.
Also sowas im Pseudocode:
unsigned char daten[sizeof(EinStruct)];
// ... daten füllen
EinStruct str = (EinStruct)daten;
Und in welcher Sprache soll der Pseudocode sein? In C# definitiv nicht,
siehe mein Posting 3 Etagen höher. Und auch in C/C++ muss man den Umweg
über Pointer gehen.
Ein Stück Code wie ich mal eine Kommunikation auf der C# Seite gebaut
habe ist im Anhang. Dabei wird erst eine Message komplett mit STX,
Daten, ETX und Blockcheck empfangen und die Daten in ein MemoryStream
geschrieben. Danach wird ein Event ausgelöst das ein Paket da ist und
ein anderer Eventhandler (könnte man auch direkt aufrufen) nimmt die
Daten auseinander.
Hallo Gemeinde,
ich komm nicht wirklich mit meinem Problem weiter !
Hab mir zwar ein fettes C# Buch gekauft aber ....?
Na ja !
Nun wollte ich fragen ob mir jemand einen kleinen Beispielcode mit
Serialisieren geben kann ??
An dieser Stelle möchte ich mich für Eure Hilfe bedanken!!!
Guten Rutsch
Gruß
Pier
Da fehlt jetzt Berechnung und die Prüfung der Checksum. Mit
fortschreitender Programmierung wirst Du auch feststellen, dass start
und ende gar nicht Teil der Struktur sein müssen, weil sie eh bekannt
sind. Beispielsweise:
Hallo & Danke erstmal,
ich hab eben den obigien Code probiert aber bekomme aber die
Fehlermeldungen nicht weg nämlich "Fehler 1 Eine implizite
Konvertierung vom Typ "System.Windows.Forms.Message" in "ComOut2" ist
nicht möglich. && Fehler 2 Der Zugriff auf "ComOut2.start" ist
aufgrund der Sicherheitsebene nicht möglich.
ich stell mich irgend wie doff an !!!
währe sehr dankbar wenn mir jemand helfen könnte
Danke und Gruß
Pier
Ich bleibe bei meiner Meinung, für Deine Aufgabe ist
Serialisieren/Deserialisieren am besten geeignet.
Wichtig ist, Dein struct/klasse mit dem Attribut Serializable() zu
versehen.
Also etwa so:
[Serializable]
struct ComOut2
{
byte start;
byte adres;
byte commando;
int eine_nummer;
unsigned char chksum;
unsigned char ende;
}
Dann musst Du einen "Stream" mit Deinen Daten machen und das ganze dann
mit einem "BinaryFormatter" serialisieren/deserialisieren, wobei
natürlich als Datentyp Dein struct angegeben werden muss.
Hier habe ich ein schönes Beispiel gefunden, welches zwar mit einer
Datei arbeitet, aber es lässt sich auch einfach für Daten von einer
seriellen Schnittstelle ändern. Aber zum üben ist es mit einer Datei
vielleicht gar nicht so schlecht.
http://forum.codecall.net/csharp-tutorials/7918-tutorial-visual-studio-2008-c-serialization.html
Pier S. wrote:
> Hallo & Danke erstmal,> ich hab eben den obigien Code probiert aber bekomme aber die> Fehlermeldungen nicht weg nämlich "Fehler 1 Eine implizite> Konvertierung vom Typ "System.Windows.Forms.Message" in "ComOut2" ist> nicht möglich. && Fehler 2 Der Zugriff auf "ComOut2.start" ist> aufgrund der Sicherheitsebene nicht möglich.>> ich stell mich irgend wie doff an !!!>> währe sehr dankbar wenn mir jemand helfen könnte>>> Danke und Gruß>> Pier
1
ComOut3Message=newMessage();
2
// Message ist nicht vom Typ Message, sondern vom Typ ComOut3, also
3
ComOut3Message=newComOut3();
4
// oder
5
ComOut3Message;
6
7
// der zweite Fehler liegt daran, das die Member wie start private sind
8
// (hätte eigentlich schon oben korrigiert werden müssen)
> // der zweite Fehler liegt daran, das die Member wie start private sind> // (hätte eigentlich schon oben korrigiert werden müssen)
Genau, hätte er eigentlich auch drauf kommen können, wenn er
entsprechende Warnungen/Fehlermeldungen angeschaut hätte.
@JoHnny:
>Ich bleibe bei meiner Meinung, für Deine Aufgabe ist>Serialisieren/Deserialisieren am besten geeignet.
Die (De)Serialilisierung mit den integrierten BinaryFormatter wird nicht
ganz klappen, da dieser, wenn auch binär, einen Header bzw.
Metainformationen schreibt/benötigt und eben nicht die Daten einfach
binär hinteinanderschreibt.
Führ mal folgendes Snipped aus und schau dir dir erstellte Datei in
einem Hexeditor an:
Weiss denn Jemand eine andere Lösung um in C# ein Byte-Array in eine
Struktur zu wandeln?
Ich habe es mit folgender Funktion probiert:
T ByteArrayToStructure<T>(byte[] bytes)
{
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
T structure =
(T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),typeof(T));
handle.Free();
return structure;
}
Leider stimmen die Byte orders zwischen µC und PC nicht überein, so dass
alle ints etc verdreht sind.
Kennt jemand eine einfache Lösung? Sollte doch irgendwie gehen...