AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Array zwischen Delphi-DLL und VB.NET
Thema durchsuchen
Ansicht
Themen-Optionen

Array zwischen Delphi-DLL und VB.NET

Ein Thema von Keex · begonnen am 24. Okt 2012 · letzter Beitrag vom 24. Okt 2012
Antwort Antwort
Keex

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

Array zwischen Delphi-DLL und VB.NET

  Alt 24. Okt 2012, 10:37
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
  Mit Zitat antworten Zitat
Morphie

Registriert seit: 27. Apr 2008
Ort: Rahden
630 Beiträge
 
#2

AW: Array zwischen Delphi-DLL und VB.NET

  Alt 24. Okt 2012, 10:55
Da VB keine Pointer unterstützt, die DLL diese aber für alles einsetzt
Ich denke das stimmt so nicht... IntPtr ist glaub ich das was du in .NET suchst... Dann kannst du die Zwischen-DLL vergessen...
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#3

AW: Array zwischen Delphi-DLL und VB.NET

  Alt 24. Okt 2012, 10:59
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: http://msdn.microsoft.com/de-de/libr...v=vs.100).aspx
  Mit Zitat antworten Zitat
Keex

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

AW: Array zwischen Delphi-DLL und VB.NET

  Alt 24. Okt 2012, 11:16
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.?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#5

AW: Array zwischen Delphi-DLL und VB.NET

  Alt 24. Okt 2012, 11:19
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.
$2B or not $2B
  Mit Zitat antworten Zitat
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
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:57 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz