Einzelnen Beitrag anzeigen

Keex

Registriert seit: 25. Feb 2004
29 Beiträge
 
#6

AW: Array zwischen Delphi-DLL und VB.NET

  Alt 24. Okt 2012, 13:37
Habe es doch noch hinbekommen, vielen Dank allen für die Hilfe
Vieleicht für andere die vor einem ähnlichen Problem stehen, werd ichs mal hinschrieben wie ich es gemacht habe:

Zunächst hole ich in meiner Zwischen-DLL in Delhi die Daten aus der Hersteller-DLL, bereite sie auf und speichere sie in einem festen, mehrdimensinalen Array:
DataReturn = array[0..1000,0..2] of double; //Erste Dimension sind die einzelnen Datenpunkte, zweite Dimension ist z.B. 0=Zeit, 1=Spannung, 2=Strom


Als Rückgabewert meiner Zwischenfunktion habe ich den Typ Pointer:

function GetCAData(FID : int32; Channel : int32) : Pointer; export; stdcall;
Die Rückgabe der Funktion ist ein Pointer auf das mehrdimensionale Array

result := @CAres; //mit CAres : DataReturn;

---------------------------------
In VB.NET werden Methoden aus folgender Klasse benötigt:
Code:
Imports System.Runtime.InteropServices
In VB importiere ich die Funktion
Code:
Private Declare Function GetCAData Lib ".\BLDelphiWrapper.dll" (FID As Int32, Channel As Int32) As IntPtr
Pointer in Delphi wird zum Datentyp IntPtr in VB.NET.


Das Lesen der Arraydaten innerhalb von VB.NET läuft nun folgendermaßen ab: Ich hole über die Delphi-Funktion den Pointer zum Anfang des Arrays. Dieses wurde in Delphi mit einem Wert -100 terminiert, da die Größe des Arrays nicht übergeben wurde. Die Daten des Arrays liegen im Speicher nach einem bestimmten Muster vor, welches mithilfe der Funktion Marshal.ReadInt64 mit verschiedenen Offsets des Basispointers ausgelesen werden kann. Die so erhaltenen Daten werden dann noch in Double konvertiert und weiterbenutzt.

Code:
Dim p As IntPtr = GetCAData(id, 0) 'Pointer zum Anfang des Arrays
            Dim it, iEwe, iI As Int64           'Int64 Daten in denen die rohen Double-Werte zwischengespeichert werden
            Dim zwischen As New List(Of BLDN_CADataResult) 'Zwischenspeicher für konvertierte Daten, da Länge nicht bekannt
            Dim sin As New BLDN_CADataResult   'Datenpunkt
            Dim count As Integer = 0    'Zähler
            Do
                'Formel für Addresse eines bestimmten Elementes: Addresse = Basisaddresse des Arrays + ElementBreite * (Zeilennummer * Spaltenanzahl + Spaltenummer)
                it = Marshal.ReadInt64(p + 8 * (count * 3 + 0)) 'Einlesen des ersten Elementes der zweiten Dimension aus der count. Zeile
                iEwe = Marshal.ReadInt64(p + 8 * (count * 3 + 1)) 'Einlesen des zweiten Elementes der zweiten Dimension aus der count. Zeile
                iI = Marshal.ReadInt64(p + 8 * (count * 3 + 2)) 'Einlesen des dritten Elementes der zweiten Dimension aus der count. Zeile
                sin.t = BitConverter.Int64BitsToDouble(it) 'Umwandeln der Daten in Double mittels Bitconverter
                sin.Ewe = BitConverter.Int64BitsToDouble(iEwe)
                sin.I = BitConverter.Int64BitsToDouble(iI)
                zwischen.Add(sin)  'Hinzufügen des Datenpunktes zur Liste
                count += 1
            Loop Until sin.t = -100 Or count >= 999 'Array ist innerhalb der Delphi-Zwischen-DLL mit -100 auf dem ersten Element terminiert

Vieleicht hilft jemandem das Prinzip bei einer ähnlichen Problemstellung.


Beste Grüße
Keex
  Mit Zitat antworten Zitat