Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   SafeArray of record (https://www.delphipraxis.net/199311-safearray-record.html)

markus888 14. Jan 2019 08:12

SafeArray of record
 
Ich versuche grade wie im Titel ein SafeArray von einem Record zu erstellen.

Laut der OLH https://docs.microsoft.com/en-us/win...earraycreateex
findet sich dazu zum Funktions Argument pvExtra folgendes:

Zitat:

pvExtra will contain a pointer to a GUID representing the type of interface being passed to the array.
Ich müsste so viel ich verstehe also einen Pointer auf einen GUID String übergeben.

Wie erstelle ich aber einen GUID auf eine record Struktur, oder gibt es eine Funktion um eine GUID zur Laufzeit aus jedem beliebigen Record zu erstellen?

Vielen Dank

TiGü 14. Jan 2019 08:33

AW: SafeArray of record
 
Der Typ TGUID aus der System.pas ist schon ein record und kein String.
Man definiert zwar GUID-Konstanten in der Art von Strings, es wird aber zur Kompilierzeit umgewandelt.

Delphi-Quellcode:
var
  vt: TVarType;
  cDims: Integer;
  rgsabound: PSafeArrayBound;
  pvExtra: pointer;
  GuidOfInterface: TGUID;
  ArrayResult: PSafeArray;
begin
  GuidOfInterface := TGUID.NewGuid;
  pvExtra := @GuidOfInterface;
  ArrayResult := SafeArrayCreateEx(vt, cDims, rgsabound, pvExtra);
end;

markus888 14. Jan 2019 08:54

AW: SafeArray of record
 
@TiGü,
danke für die Antwort.

Leider weiß ich jetzt nicht wie ich das umsetzen muss.

Angenommen ich habe folgenden Record:

Code:
TRecSample = packed record
  ID: Integer;
  Text: WideString;
  Value: Byte;
  end;
Wie bekomme ich davon einen verwertbaren GUID, damit der SafeArray korrekt erstellt werden kann?

TiGü 14. Jan 2019 09:15

AW: SafeArray of record
 
Oh, ich nahm an, du willst ein Array mit Interface-Instanzen übergeben.
Du willst also stattdessen ein Array mit deinen Record namens TRecSample übergeben?
Schauen wir uns dazu nochmal die Doku an:

Zitat:

pvExtra

the type information of the user-defined type, if you are creating a safe array of user-defined types. If the vt parameter is VT_RECORD, then pvExtra will be a pointer to an IRecordInfo describing the record. If the vt parameter is VT_DISPATCH or VT_UNKNOWN, then pvExtra will contain a pointer to a GUID representing the type of interface being passed to the array.
Ich nehme an, du hat als ersten Parameter den Wert VT_RECORD und nicht VT_DISPATCH or VT_UNKNOWN, richtig?
Dann musst du eine Instanz einer Klasse übergeben, welche IRecordInfo implementiert.
Hier ein bisschen zum Nachlesen:
https://stackoverflow.com/questions/...ype-to-vb6-dll

markus888 14. Jan 2019 09:39

AW: SafeArray of record
 
@TiGü, danke für deinen Support.


Hat irgendwer eine Idee oder ein Beispiel, wie ich nun diese IRecordInfo für einen Record erstellen kann?

Edit:
Bitte kein workaround.
Ich übergebe die Daten via dll an VBA.
Ich kann von VBA aus ein Safearray mit einem oder mehreren Elementen übergeben und in Delphi dann mit Redim arbeiten.
Hätte aber lieber eine saubere Lösung.

Hinweis:
Ich verwende keine COM DLL, sondern eine Standard DLL, aber vermutlich ist eine Typbibliothek notwendig.

TiGü 14. Jan 2019 10:25

AW: SafeArray of record
 
Kann ich fragen, was genau das Ziel ist? Ggf. lässt sich ein Datenaustausch zwischen den Modulen auch einfacher bewerkstelligen, wenn du beide Seiten anpassen kannst.

markus888 14. Jan 2019 11:23

AW: SafeArray of record
 
Zitat:

Zitat von TiGü (Beitrag 1423283)
Kann ich fragen, was genau das Ziel ist? Ggf. lässt sich ein Datenaustausch zwischen den Modulen auch einfacher bewerkstelligen, wenn du beide Seiten anpassen kannst.

Es geht um den Datenaustausch zwischen VBA und einer Standard Dll.
Ich bin derzeit noch in der Kennenlernphase von Delpi.
Hab vor wenigen Wochen begonnen mich mit dem Thema DLL zu beschäftigen - es geht um die Kommunikation mit VBA.

Das Handling mittels SafeArray ist soweit kein Problem (mehr). Auch das erzeugen bei Standard Datentypen geht ja einfach.
Jetzt geht es mir nur darum, direkt in Delphi ein SafeArray zu erstellen, dass einen Record zurückgibt.
Der Record wird auf beiden Seiten definiert und somit sind die Daten auf beiden Seiten lesbar.
Als workaround übergebe ich derzeit von VBA aus eine Ref auf ein Safearray oder ein OleVariant mit Safearray als Untertyp mit mindestens einem Element.
Dann kann ich falls erforderlich in der DLL per Redim die Anzahl der Elemente anpassen.

Im nächsten Schritt möchte ich mich dann noch mit COM DLL befassen.

peterbelow 14. Jan 2019 11:57

AW: SafeArray of record
 
Ganz so einfach ist das nicht. Eigentlich sollte die die VBA-Anwendung für ihren user-defined type ein IRecordInfo interface registriert haben, jedenfalls wenn sie diesen Typ für die externe Verwendung via COM/Ole automation vorgesehen hat. Wenn das nicht der Fall ist müßtest Du selbst eine COM-DLL basteln, die eine Implementierung von IRecordInfo bereitstellt, die der Recordstruktur entspricht, und diese registrieren.

Gibt es eventuell zu der Anwendung eine Type library, die Du importieren könntest?

markus888 14. Jan 2019 12:12

AW: SafeArray of record
 
@peterbelow,
wie gesagt mit COM DLL habe ich mich noch nicht beschäftigt.
Es ist eine Standard DLL.

Wie das mit der Typelib geht weiß ich noch nicht.
LG Markus

markus888 14. Jan 2019 19:33

AW: SafeArray of record
 
Liebe Helfer,
jetzt weiß ich, dass ich eine Typlib brauche.
Kann mich erst nächste Woche wieder damit beschäftigen.
Hab kurz drüber gschaut und es sollte kein Problem darstellen.

Danke an alle.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:10 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