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
Gast
#1064025
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).
Giebt es keine besser lösung für meine structur ??? Irgend wie byte für byte weiterschieben oder so ???? Gruß Pier
Gast
#1064848
Es gibt in C# keine Pointer ? http://msdn.microsoft.com/en-us/library/50sbeks5.aspx Ich vermute mal ihr meint das mit "Poiter" MFG Marco
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 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
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)
1 | |
2 | |
3 | |
4 | |
5 | |
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.
Kleiner Nachtrag: Bei der dritten Variante kann man auch gleich die u.U. nötigen Byte-Order Umwandlungen eleganter miterledigen lassen.
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
Gast
#1065639
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
Gast
#1065665
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.
Gast
#1065682
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.
Vielen Dank für Eure Hilfe !!! Werd mich auf die suche machen !!! Bin wol zu Hartwarebezogen eingestelt !! Gruß Pier
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;
Gast
#1067129
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
Gast
#1098036
So vielleicht:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
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:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
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
Gast
#1099085
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
Danke für deine Hilfe ich schau mir das Beispiel gleich an! Gruß Pier
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 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
Gast
#1099174
> // 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:
1 | |
2 | |
3 | |
4 | |
5 | |
greets
Gast
#1135012
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...
Gast
#1221521
Beispiel:
Eine Structure ist definiert als:
Hinweis:
Die Struct ist als unsafe deklariert, da sie zwei char arrays fester
Größe besitzen soll. (Eines ist public fixed byte JobID[28])
[StructLayout(LayoutKind.Explicit, Size = 184)]
unsafe struct MetaData
{
[FieldOffset(0)] //1 bytes
public byte MetaDataVersion;
[FieldOffset(1)] //1 bytes
public byte Channel_FFTLength;
[FieldOffset(2)] //2 bytes
public Int16 Reserved1;
[FieldOffset(4)] //28 bytes
public fixed byte JobID[28];
[FieldOffset(32)] //8 bytes
public Int64 XOversampling;
[FieldOffset(40)] //8 bytes
public Int64 YStart;
[FieldOffset(48)] //8 bytes
public Int64 YDelta;
[FieldOffset(56)] //8 bytes
public Int64 YRange;
[FieldOffset(64)] //8 bytes
public Int64 ProcessingGain;
[FieldOffset(72)] //8 bytes
public Int64 Reserved2;
[FieldOffset(80)] //1 bytes
public byte Jop_Gap_ADCOverload;
[FieldOffset(81)] //1 bytes
public byte DataVideofiltered;
[FieldOffset(82)] //2 bytes
public Int16 Reserved3;
[FieldOffset(84)] //4 bytes
public Int32 Antenna;
[FieldOffset(88)] //8 bytes
public Int64 Centerfreq;
[FieldOffset(96)] //8 bytes
public Int64 XDelta;
[FieldOffset(104)] //8 bytes
public Int64 Duration;
[FieldOffset(112)] //8 bytes
public Int64 Attenuation;
[FieldOffset(120)] //8 bytes
public Int64 GainCorrection;
[FieldOffset(128)] //8 bytes
public Int64 DetectorHfFrequency;
[FieldOffset(136)] //4 bytes
public Int32 DetectorHfSignalValue;
[FieldOffset(140)] //4 bytes
public Int32 DetectorHfSignalDelta;
[FieldOffset(144)] //40 bytes
public fixed byte Reserved4[40];
}
Mit folgender Funktion kann man sich die Structur aus einem Byte Array
herausholen. Der Ansatz ist oben schon besprochen worden (Autor Arcnet
1.12.2008 Lösungsnummer 2):
private static Header GetHeader( byte[] InBuffer)
{
Header Localheader = new Header();
byte[] Buffer = new byte[Marshal.SizeOf(Localheader)];
IntPtr pntHeader =
Marshal.AllocHGlobal(Marshal.SizeOf(Localheader));
try
{
BinaryReader reader = new BinaryReader(new
MemoryStream(InBuffer));
Buffer = reader.ReadBytes(Marshal.SizeOf(Localheader));
Marshal.Copy(Buffer, 0, pntHeader,
Marshal.SizeOf(Localheader));
Localheader = (Header)Marshal.PtrToStructure(pntHeader,
typeof(Header));
DateTime dtTOA = new DateTime(1970, 01, 01, 0, 0, 0,
DateTimeKind.Utc) + new TimeSpan(Localheader.TOA * 10);
return Localheader;
}
catch
{
return Localheader;
}
finally
{
// Free the unmanaged memory.
Marshal.FreeHGlobal(pntHeader);
}
}
Gruß JG
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.