Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Empfohlene Antworten

Veröffentlicht

Hallo ihr Lieben,

ich habe ein Byte-Array mit Daten. Nun möchte ich einer Funktion einen Zeiger auf eine Adresse in diesem Array übergeben. Innerhalb dieser Funktion möchte ich dann ein Array auf diese Adresse mappen (nur n Byte ab der angegebenen Adresse). Geht sowas nur mit unsafe oder gibt es einen eleganteren Weg?

Grüße

Steinadler

  • Autor

Ich habe einen Byte-Abbild vorliegen. Da drin liegen an bestimmten Adressen 8/16/32-Bit-Werte.

In meinem Projekt, möchte ich diese Daten nun auf meine Objekte innerhalb der Klassenstruktur mappen, sprich wenn sich das zugehörige Byte im Datenstrom ändert, soll sich auch der Wert in meinem Objekt ändern. Eine Referenz auf ein einziges Byte ist kein Problem, aber ich möchte ja auch Werte aus dem Datenstrom nutzen, die größer ein Byte sind.

Darum dachte ich, ich könnte einfach pro Objekt eine Startadresse im Byte-Abbild zuweisen und innerhalb des Objektes dann die gewünschte Anzahl Bytes ab dieser Adresse nutzen.

In C hätte ich es so gemacht. Aber in C#?

  • Autor
nochmal: was möchtest du überhaupt tun? Adressen gehampel macht man in C# eigentlich nicht.

Also nochmal: Ich habe ein Byte-Array mit z.B. 100 Werten (Index 0..99). Ab Index 0 liegt ein Byte, ab Index 1 Liegt ein 32-Bit-Int und ab Index 5 liegt ein String, welcher aus 12 Bytes besteht. Also sieht mein Array folgendermaßen aus

array[0] -> Byte0

array[1] -> Int0

array[2] -> Int0

array[3] -> Int0

array[4] -> Int0

array[5] -> String0

array[6] -> String0

array[7] -> String0

array[8] -> String0

array[9] -> String0

array[10] -> String0

array[11] -> String0

array[12] -> String0

array[13] -> String0

array[14] -> String0

array[15] -> String0

array[16] -> String0

array[17] -> String0

Ich habe eine Klasse angelegt, welche einen beliebigen Wert wiedergeben kann (Typ object). Die Bitlänge ist per Konstruktor angebbar.

Und über Instanzen dieser Klasse möchte ich dann auf den Inhalt des Datenabbildes zugreifen.

Nur bin ich mir nicht sicher, wie ich am klügsten der Instanz ihren Bereich im Datenabbild zuweise.

Von höherer Stelle möchte ich dann z.B. sagen label1.Text = IntObject.Value.ToString();

und IntObject müsste dann den Wert an Stelle x im Datenabbild zurückgeben.

Bearbeitet von steinadler

  • Autor
Woher bekommst du das Array?

Eine der staerken von C# ist, dass es Typesafe ist - das hier widerspricht jeglicher Intension von C#.

Das bekomme ich von einer seriellen Schnittstelle, welche mir aller paar Sekunden diese Daten sendet.

  • Autor
das macht man in C# so nicht ;-) Ich frage mich auch ehrlich gesagt, wo der praktische nutzen liegen sollte. Hast du ein konkretes Problem was du so lösen möchtest? Vielleicht können wir zusammen einen anderen Ansatz finden.

Gut, also anders gefragt: Wie kann ich elegant aus einer Oberfläche auf Werte zugreifen, die mit unterschiedlicher Länge in einem Datenabbild welches zyklisch über die serielle Schnittstelle eingelesen wird, liegen?

*edit* Frage wurde weiter oben bereits beantwortet.

Wie bereits erwähnt macht man das in dem man einen Event abfeuert. Macht dir einen Thread der die Daten der seriellen Schnittstelle empfängt und einen Event feuert sobald sich etwas im Array ändert.

Bearbeitet von trollr

  • Autor
*edit* Frage wurde weiter oben bereits beantwortet.

Wie bereits erwähnt macht man das in dem man einen Event abfeuert. Macht dir einen Thread der die Daten der seriellen Schnittstelle empfängt und einen Event feuert sobald eine Änderung (?) eintritt. Dann schickst du der Form über den Event die Daten

Dann muss ich aber die gesamte Auswertelogik in meinem Formular machen, das wollte ich eigentlich nicht.

*vorheriges Post angepasst*

Nein das kannst du ebenfalls in dem Thread machen. Wieso auch nicht? Du musst ja nicht nach jedem Byte einen Event feuern, sondern meinetwegen auch nur wenn passende Daten vorhanden sind.

--> Sobald "Hallo" empfangen -> Trigger Event "receivedHallo"

Ich würde übrigens kein Array dafür nutzen.

  • Autor
Schreib dir in deinem Business Layer einen Parser der dir die Daten auswertet. Daten an die View würde ich per MVVM Pattern machen. Machst du eigentlich Windows Forms oder WPF?

Windows Forms.

Den Datenstrom kann ich nicht verändern. Ich bekomme immer ein Byte-Array fester Länge zurück. Anhand einer Tabelle weiß ich, an welcher Position im Abbild die Daten stehen müssen. Meines Erachtens nach brauche ich eine Zwischenschicht, die daraus typsichere Objekte generiert.

Möglich wäre im Prinzip ein Objekt mit folgenden Eigenschaften zu erstellen:

object Wert;

int IndexImAbbild;

ref byte[] Abbild;

dann könnte das Objekt selbst seine Daten aus dem Abbild holen.

Aber ich dachte an eine Möglichkeit, dem Objekt nicht das gesamte Abbild übergeben zu müssen sondern nur ab einer bestimmten Adresse - quasi den relevanten Teil.

Ich wollte gerne aus Performancegründen vermeiden, dass ich das Byteabbild mit einer Schleife durchkaspern muss.

  • Autor
Das ist genau der Punkt warum ich sage Parser ;-)

Du musst das Muster finden, mit dem du die relevanten Daten zuverlässig aus dem Datenstrom ziehen kannst. Ne Schleife ist im Zweifel nicht zu Performancelastig.

Also müsste ich das ganze Array durchlaufen und jedem Objekt die richtigen Werte zuweisen/zucasten?

  • Autor
wie kriegst du die daten denn von der schnittstelle? was kommt bei dir an? und welche Informationen davon interessieren dich tatsächlich

Ich bekomme immer ca. 5000 Bytes.

Und tatsächlich interessieren mich dann alle enthaltenen Werte, Integer, Bytes, Strings, von welchen ich wiederum weiß, an welcher Stelle des datenabbildes sie liegen und wieviele Bytes sie jeweils einnehmen.

Ich glaube, es ist noch nicht wirklich ersichtlich, was Du wann wie und wo benötigst.

Ich wollte gerne aus Performancegründen vermeiden

Dann benutze gleich C++.

array[0] -> Byte0

array[1] -> Int0

array[2] -> Int0

array[3] -> Int0

array[4] -> Int0

array[5] -> String0

array[6] -> String0

array[7] -> String0

array[8] -> String0

array[9] -> String0

array[10] -> String0

array[11] -> String0

array[12] -> String0

array[13] -> String0

array[14] -> String0

array[15] -> String0

array[16] -> String0

array[17] -> String0

In meinem Projekt, möchte ich diese Daten nun auf meine Objekte innerhalb der Klassenstruktur mappen, sprich wenn sich das zugehörige Byte im Datenstrom ändert, soll sich auch der Wert in meinem Objekt ändern.

--> Sobald "Hallo" empfangen -> Trigger Event "receivedHallo"

http://de.wikipedia.org/wiki/Observer_(Entwurfsmuster)

Das ist das, was Dir weiterhelfen sollte.

Du baust eine Struktur auf, wo sich unterschiedliche Objekte für unterschiedliche Teile des Arrays als Subscriber melden und erhalten just auch nur den Teil, den sie benötigen.

Die Sache mittels Zeigern zu lösen geht im managed C# natürlich nicht.

Allerdings solltest Du Dir deswegen keine grauen Haare wachsen lassen:

a) existiert zwar in C# lediglich ein Call-by-Value

B) ist das nicht weiter schlimm, da es ja die Referenztypen gibt; i.e. bei einem Objekt wird eben die Referenz per value übergeben, was der Übergabe eines Zeigers in anderen Sprachen entspricht.

  • Autor
Du baust eine Struktur auf, wo sich unterschiedliche Objekte für unterschiedliche Teile des Arrays als Subscriber melden und erhalten just auch nur den Teil, den sie benötigen.

Das ist das, wie ich es jetzt realisiert habe, nur dass das Kind dadurch einen Namen bekommen hat ;-)

Ich geb dann den Objekten trotzdem das ganze Byte-Abbild referenziell mit und jedes Objekt holt sich daraus dann die entsprechenden Daten die es braucht. Richtig?

Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.