![]() |
Array zwischen Delphi-DLL und VB.NET
Hallo zusammen,
ich benutze eine Hersteller DLL um auf eines meiner Messgeräte zuzugreifen. Die DLL ist in Delphi geschrieben und ich möchte sie in VB.NET verwenden. Da VB keine Pointer unterstützt, die DLL diese aber für alles einsetzt, habe ich noch eine Zwischen-DLL in Delphi geschrieben die die Kommunikation mit der Hersteller-DLL übernimmt und die Daten dann für meine VB-Applikation aufbereitet. Alles wie gesagt kein Problem, außer bei der Übergabe der Daten während einer Messung. Die Hersteller-DLL schreibt die Daten in einen Buffer den man dann mit einer Funktion auslesen kann. Problematisch ist, dass ich nun ein Array mit Daten in meiner Zwischen-DLL habe, was ich an VB weitergeben möchte. Bisher ist es mir nicht gelungen, dass ganze zu bewerkstelligen. Wenn ich versuche, einfach das Array als Funktionsresultat bereitzustellen:
Code:
CADataResult = record
Ewe : single; I : single; t : double; end; CAData = record Data : array of CADataresult; end; ----- function GetCAData(FID : int32; Channel : int32) : CAData; export; stdcall; schmeißt VB eine Exception "Die Typensignatur der Methode ist nicht PInvoke-kompatibel.". Weiss jemand eine Möglichkeit, wie man so etwas realisieren kann? Ich muss dazu sagen, dass ich kein Profi bin, und das ganze eher aus der Notwendigkeit geboren ist, daher entschuldige ich mich mal für offensichtliche Fehler. Falls ihr noch Informationen benötigt, immer gern. Danke bereits im Vorraus und beste Grüße Keex |
AW: Array zwischen Delphi-DLL und VB.NET
Zitat:
|
AW: Array zwischen Delphi-DLL und VB.NET
Zu der array übergabe wäre auch noch die Deklaration in .net interessent. Funktionieren müsste auch das.
Dazu gibt es auch ein Beispiel im msdn: ![]() |
AW: Array zwischen Delphi-DLL und VB.NET
meine Structures in VB sehen folgendermaßen aus:
Code:
Public Structure BLDN_CADataResult
Dim Ewe As Single Dim I As Single Dim t As Double End Structure Public Structure BLDN_CAData Dim Data() As BLDN_CADataResult End Structure --------------------- Private Declare Function GetCAData Lib ".\BLDelphiWrapper.dll" (FID As Int32, Channel As Int32) As BLDN_CAData Mich verwirrt leider das ganze System ein wenig. Selbst wenn ich jetzt einen Pointer aus Delphi an VB übergeben würde, wie würde ich dann wissen wie die Daten an der Addresse wirklich gespeichert sind? Wenn es jetzt ein Array aus Integer-Werten wäre, wäre es ja relativ einfach wenn ich die Länge des Arrays kenne, aber mit dem Array aus der Structure find ich das schwieriger. In welcher Reihenfolge werden die Array Daten gespeichert z.B.? |
AW: Array zwischen Delphi-DLL und VB.NET
Wobei dieses dynamische Array auch noch ein Delphityp ist, welchen VB vermutlich nicht kennt.
Abgesehn davon daß er über den Delphi-MemoryManager behandelt wird und SharedMM wirst du hier bestimmt nicht benutzen. |
AW: Array zwischen Delphi-DLL und VB.NET
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:
Delphi-Quellcode:
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:
Delphi-Quellcode:
function GetCAData(FID : int32; Channel : int32) : Pointer; export; stdcall;
Die Rückgabe der Funktion ist ein Pointer auf das mehrdimensionale Array
Delphi-Quellcode:
result := @CAres; //mit CAres : DataReturn;
--------------------------------- In VB.NET werden Methoden aus folgender Klasse benötigt:
Code:
In VB importiere ich die Funktion
Imports System.Runtime.InteropServices
Code:
Pointer in Delphi wird zum Datentyp IntPtr in VB.NET.
Private Declare Function GetCAData Lib ".\BLDelphiWrapper.dll" (FID As Int32, Channel As Int32) As IntPtr
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 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:43 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz