Announcement

Collapse
No announcement yet.

Marshalling bei dynamischen Arrays

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Marshalling bei dynamischen Arrays

    Hallo,
    ich möchte mit einer externen Hardware Daten austauschen. Dazu übergebe ich ein Byte-Array an eine Dll. Um die Daten auswerten zu können kopiere ich sie mittels Marshal.PtrToStructure in die jeweils passende Struktur. Nun zu meinem Problem: Ich arbeite mit verschiedenen Strukturen, die teilweise Arrays mit mit dynamischer Länge enthalten. Zur Verarbeitung von Arrays mit fester Größe gibt es ja einige Beispiele im Netz, aber die beschneiden mir mein dynamisches Array auf ein einziges Element, wenn ich keine ConstSize vorgebe. Wer kann mir sagen, wie man hier vorgehen muss?
    Vielen Dank im voraus!

  • #2
    In welche Richtung möchtest Du dein dynamisches Array (z.B. ArrayList) schicken? Managed nach Unmanaged?

    Comment


    • #3
      Hmmm, ich hoffe ich habe mich nicht falsch ausgedrückt. Meine Strukturen sehen ungefähr so aus:
      Code:
              public struct A
              {
                  public ushort a;
                  public byte b;
                  public short c;
                  public ushort arrayLength;
                  public int[] array;
              }
      Dynamisch oder vielleicht besser gesagt von Fall zu Fall unterschiedlich ist dabei eigentlich nur die Anzahl der Bytes, die in die Strukturvariable hineinkopiert werden sollen bzw. das Byte-Array, das aus einer Strukturvariable generiert werden soll. Die Strukturen sollen genau das Datenformat wiedergeben in dem die Daten im Byte-Array übertragen werden sollen.
      Zuletzt editiert von cairn; 20.11.2007, 13:58.

      Comment


      • #4
        Bin mir nicht ganz sicher wo das Problem liegt.
        Geht es um das Array im struct?

        Geht das was Du benötigtst in die Richtung (letzes Posting (von mir)):
        http://entwickler-forum.de/showthread.php?t=43022

        Was ich glaub verstanden zu haben, dass es immer um Arrays geht. Nicht, wie von mir vermutet um ArrayLists oder ähnlich. Oder??

        Gruss Simon

        Comment


        • #5
          Zeig doch mal alles her:
          Die C# Seite und die C/C++ Seite.
          Interessieren tun die Deklarationen der Funktionen und Strukturen.

          Comment


          • #6
            O.k., mein Problem ist nicht die Datenübergabe an die DLL. Die funktioniert. Mein Problem ist die anschließende Umwandlung der Daten aus dem Byte-Array, das ich von der Dll bekomme. Hier erst mal ein bisschen Quellcode:
            Code:
                [StructLayout(LayoutKind.Sequential)]
                public struct TelInitResponseData
                {
                    public ushort encodedLength;
                    public byte telNr;
                    public byte versionMicro;
                    public byte versionFPGA;
                    public ushort anzSlaves;
                    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1)]
                    public byte[] versNums;
                }
                //...
            
                 private TelInitResponseData Deserialize(byte[] arr)
                 {
                        return RawDeserialize<TelInitResponseData>(arr);
                 }
            
            
                 private T RawDeserialize<T>(byte[] rawdata)
                 {
                        if (Marshal.SizeOf(typeof(T)) > rawdata.Length)
                            throw new ArgumentException("Invalid length");
                        T retObj;
                        GCHandle handle = GCHandle.Alloc(rawdata, GCHandleType.Pinned);
                        try
                        {
                            IntPtr buffer = handle.AddrOfPinnedObject();
                            retObj = (T)Marshal.PtrToStructure(buffer, typeof(T));
                        }
                        finally
                        {
                            handle.Free();
                        }
                        return retObj;
                }
            Bevor der oben gezeigte Code ausgeführt wird, identifiziere ich zuerst in welchem Format die Daten vorliegen. Gehen wir mal davon aus das in diesem Fall das Format durch die Struktur TelInitResponseData beschrieben wird. Dann möchte ich mit der Methode Deserialize die Daten aus dem Daten-Array in die entsprechende Struktur übertragen. Das funktioniert auch wie oben gezeigt, wenn ich in dem MarshalAs-Attribut eine ConstSize vorgebe. Aber das ist genau mein Problem: das Array versNums hat nicht immer die gleiche Größe. Die Größe des Arrays bekomme ich im Datenfeld anzSlaves übertragen...
            Ich hoffe das trägt etwas zur Klärung bei.

            Comment


            • #7
              Ich lese jetzt die Arrays mit flexibler Größe seperat mit der Bitconverter-Klasse ein. Die RawSerialize-Methode kann ich dann wenigstens auf die feststehenden Datenstrukturen anwenden. Eine andere Lösung habe ich leider nicht gefunden.

              Comment

              Working...
              X