Inhalte verschiedener Byte[] verknüpfen



  • Hallo,

    in meinem Programm habe ich eine beliebige Anzahl kleinerer Byte-Arrays. Deren Inhalt wird zusätzlich in mehreren, verschiedenen größeren Byte-Arrays nach bestimmten Vorgaben zusammengefasst. Also entspricht jeweils ein Teil des Inhalts eines großen Byte-Arrays dem Inhalt eines kleinen Byte-Arrays.

    Beispiel:
    Namen Kleine Byte-Arrays: A, B, C, D
    Großes Byte-Array 1 besteht aus A + C + D
    Großes Byte-Array 2 besteht aus A + B + C
    Großes Byte-Array 3 besteht aus C + D + B

    Mein Ziel ist es, dass bei einer Änderung eines Bytes im kleinen Byte-Array automatisch auch das entsprechende Byte in allen großen Byte-Arrays verändert wird. Wird also ein Byte im Byte-Array A geändert, dann sollte diese Änderung auch sofort in den großen Byte-Arrays 1 und 2 erfolgen. Welcher Ansatz ist hierfür sinnvoll?

    Vorab Danke...



  • * du könntest mit Events arbeiten die die kleinen auslösen und die großen abonnieren.
    * du könntest die großen in Objekte kapseln, intern auf die kleinen verweisen und ein Indexer definieren der dann die Werte aus den kleinen holt.



  • Referenzen sind hier schon recht sinnvoll.

    kuck-kuck
    🙂


  • Administrator

    kuckuck+ schrieb:

    Referenzen sind hier schon recht sinnvoll.

    😕

    @Guenz,
    Falls du keinen Index-Zugriff bei den grossen Arrays benötigst, könntest du diese über Linq mit Concat zusammenfügen.

    Grüssli



  • Referenzen sind hier schon recht sinnvoll.

    class MyByte
    {
       public byte Data{get; set;}
    }
    
    MyByte A= new MyByte();
    MyByte B= new MyByte();
    MyByte C= new MyByte();
    MyByte D= new MyByte();
    
    List<MyByte> listA=new List( new[]{ A, B, C});
    List<MyByte> listB=new List( new[]{ D, B, A});
    

    so werden die "Bytes" in jeder liste angepasst, syncronisiert.. willst du nun ein byte Array

    byte[] array= listA.Select(it=>Data).ToArray();
    


  • kuckuck++ schrieb:

    class MyByte
    {
       public byte Data{get; set;}
    }
    

    1. Lösung ist falsch. Er will kleine Byte-Arrays kombinieren nicht einzelne Bytes.

    kuckuck++ schrieb:

    byte[] array= listA.Select(it=>Data).ToArray();
    

    2. lösung ist ineffizient, das das Zielrray bei jeder Änderung neu aufgebaut werden muß da die Werte kopiert werden müssen.



  • Zu 1. du hast recht.

    Zu 2. in wie weit es effizent sein muss hängt von der nutzen ab. Wenn er nur 1 mal pro stunden sowas machen muss ist es völlig egal.



  • Achso das ganze mit byte-Array blöcke:

    class MyByteArray
    {
       public byte[] Data{get; set;}
    }
    
    MyByteArray A= new MyByteArray();
    MyByteArray B= new MyByteArray();
    MyByteArray C= new MyByteArray();
    MyByteArray D= new MyByteArray();
    
    List<MyByteArray> listA=new List( new[]{ A, B, C});
    List<MyByteArray> listB=new List( new[]{ D, B, A});
    
    byte[] array= listA.SelectMany(it=>Data).ToArray();
    

  • Administrator

    kuckuck++ schrieb:

    Achso das ganze mit byte-Array blöcke:

    Wie kompliziert willst du das denn noch lösen? Siehe meinen Vorschlag! Du brauchst diese ganze Indirektion über MyByteArray gar nicht. Die Listen sind auch unnötig und die Linq Anweisung daher am Ende nur wahnsinnig kompliziert. Achja, dort machst du nochmals einen Fehler, du erstellst daraus ein neues byte Array. Dieses byte Array steht aber in keiner Beziehung mehr zu deinen MyByteArray Objekten und deren Werten.

    Alles was es benötigt, ist dies hier:

    byte[] lhs = { 1, 2, 3 };
    byte[] rhs = { 4, 5, 6 };
    
    IEnumerable<byte> bigArray = lhs.Concat(rhs);
    

    Grüssli



  • Hallo,

    vielen Dank erstmal für Eure Antworten und sorry, dass ich mich erst jetzt melde (hatte doch noch kurzfristig Urlaub...).

    Die Lösung sollte auf jeden Fall effizient sein, da ich das ganze mehrfach alle 5ms machen muss.

    In meiner jetzigen Umsetzung habe ich testweise das große Array als Byte-Pointer-Array umgesetzt und die einzelnen Bytes der kleinen Byte-Arrays folgendermaßen verknüpft:

    ...
    unsafe private void TestVerknuepfung()
    {
       this.bNichtInit = true;
       for (int i = 0; i < this.test1.ByArray.Length; i++) {
          fixed (byte* testByte = &this.test1.ByArray[i]) {
             TestFrame.byDaten[i] = testByte;
          }
       }
       for (int i = 8; i < 16; i++) {
          fixed (byte* testByte = &this.test2.ByArray[i-8]) {
             TestFrame.byDaten[i] = testByte;
          }
       }
    }
    ...
    
    //Objekt eines kleinen Byte-Arrays
    namespace SchnellTest
    {
        unsafe public class Test
        {
            public Test(bool b) 
            {
                if (b) {
                    for (int i = 0; i < this.ByArray.Length; i++) {
                        this.ByArray[i] = (byte)i;
                    }
                }
                else {
                    for (int i = 0; i < this.ByArray.Length; i++) {
                        this.ByArray[i] = (byte)(8 - i);
                    }
                }
            }
            public Byte[] ByArray = new Byte[8];
        }
    }
    
    //Objekt des großen Byte-Arrays:
    namespace SchnellTest
    {
        unsafe public class Frame
        {
            public Frame() {}
    
            public Byte*[] byDaten= new Byte*[16];
        }
    }
    

    Der Test lieferte das gewünschte Ergebnis, ich bin mir aber noch unsicher, ob mir der GarbageCollector nicht Probleme bereitet und bspw. die "Adressen der kleinen Byte-Arrays" verwurstelt. Auch wegen der Performance bin ich mir nicht sicher. Habt Ihr dazu Informationen?

    Den Vorschlag bezüglich Concat habe ich noch nicht weiter verfolgt, da ich momentan noch nicht ein Framework >= 3.5 benutze, werde ich dann aber bei Gelegenheit noch nachholen.


Anmelden zum Antworten