AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

OleVariant PSafeArray

Ein Thema von Berni68 · begonnen am 5. Jan 2022 · letzter Beitrag vom 10. Jan 2022
Antwort Antwort
Berni68

Registriert seit: 9. Jan 2006
Ort: Villingen
162 Beiträge
 
Delphi XE5 Professional
 
#1

OleVariant PSafeArray

  Alt 5. Jan 2022, 14:32
Hallo,

in einer Typbibliothek ist folgende Funktion definiert:
Delphi-Quellcode:
// *********************************************************************//
// DispIntf: ModelState
// Flags: (4096) Dispatchable
// GUID: {B0D75815-A121-4964-BE90-7B8C0422C2DD}
// *********************************************************************//
  ModelState = dispinterface
    ['{B0D75815-A121-4964-BE90-7B8C0422C2DD}']
    ...
    procedure GetReferenceKey(var ReferenceKey: {NOT_OLEAUTO(PSafeArray)}OleVariant;
                              KeyContext: Integer); dispid 2130706454;
    ...
  end;
Damit will ich die Funktion aufrufen:
Delphi-Quellcode:
...
var
  test: OleVariant;

begin
  ...
  MS.Item[i].Name // <- funktioniert
  ...
  test:= VarArrayCreate([0,1000],varByte);
  MS.Item[i].GetReferenceKey(test); // <- funktioniert NICHT
  ...
Der Aufruf der Prozedur scheitert. ich erhalte bei der Zeile "MS.Item[i].GetReferenceKey(test)" die Fehlermeldung Typenkonflikt.

bedeutet wohl daß
VarArrayCreate([0,1000],varByte)
falsch ist.
Aber wie muß das definiert werden?
Wie erzeuge ich hier ein PSafeArray ?
Bernhard

Geändert von Berni68 ( 5. Jan 2022 um 14:43 Uhr)
  Mit Zitat antworten Zitat
peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
672 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: OleVariant PSafeArray

  Alt 5. Jan 2022, 15:05
Hallo,

in einer Typbibliothek ist folgende Funktion definiert:
Delphi-Quellcode:
// *********************************************************************//
// DispIntf: ModelState
// Flags: (4096) Dispatchable
// GUID: {B0D75815-A121-4964-BE90-7B8C0422C2DD}
// *********************************************************************//
  ModelState = dispinterface
    ['{B0D75815-A121-4964-BE90-7B8C0422C2DD}']
    ...
    procedure GetReferenceKey(var ReferenceKey: {NOT_OLEAUTO(PSafeArray)}OleVariant;
                              KeyContext: Integer); dispid 2130706454;
    ...
  end;
Damit will ich die Funktion aufrufen:
Delphi-Quellcode:
...
var
  test: OleVariant;

begin
  ...
  MS.Item[i].Name // <- funktioniert
  ...
  test:= VarArrayCreate([0,1000],varByte);
  MS.Item[i].GetReferenceKey(test); // <- funktioniert NICHT
  ...
Der Aufruf der Prozedur scheitert. ich erhalte bei der Zeile "MS.Item[i].GetReferenceKey(test)" die Fehlermeldung Typenkonflikt.

bedeutet wohl daß
VarArrayCreate([0,1000],varByte)
falsch ist.
Aber wie muß das definiert werden?
Wie erzeuge ich hier ein PSafeArray ?
Was ist MS? So wie GetReferenceKey definiert ist würde ich erwarten, das diese Prozedur den array erzeugt und in dem test-OleVariant zurückgibt. Du übergibst auch keinen Wert für den KeyContext-Parameter. GetReferenceKey gibt auch keinen Result zurück, den Du einer Variablen zuweisen kannst.
Peter Below
  Mit Zitat antworten Zitat
Berni68

Registriert seit: 9. Jan 2006
Ort: Villingen
162 Beiträge
 
Delphi XE5 Professional
 
#3

AW: OleVariant PSafeArray

  Alt 5. Jan 2022, 15:22
Die ganze Prozedur sieht so aus:

Delphi-Quellcode:
procedure TMain.MI_InfoPartClick(Sender: TObject);
var
  doc: Document;
  ipt: PartDocument;
  MS: ModelStates;
  i: integer;
  test:OleVariant;
begin
  doc:= InventorApp.ActiveDocument;
  memo.Lines.Add(doc.FullDocumentName);
 
  if doc.DocumentType <> PartDocumentObject then exit;
  ipt:= PartDocument(doc);
  MS:= ipt.ComponentDefinition.ModelStates;

  test:= VarArrayCreate([0,1000],varByte);

  for i:=1 to MS.Count do begin
    memo.Lines.Add(MS.Item[i].Name); // funktioniert
    //MS.Item[i].Activate; // funktioniert
    memo.Lines.Add(MS.Item[i].Document.PropertySets.Item[1].Item[1].Value); // funktioniert (auch schreibend)

    MS.Item[i].GetReferenceKey(test, 0); // Typkonflikt
  end;
end;
Nur der Aufruf der Prozedur
GetReferenceKey(test, 0);
geht nicht: Typenkonflikt
Bernhard
  Mit Zitat antworten Zitat
Berni68

Registriert seit: 9. Jan 2006
Ort: Villingen
162 Beiträge
 
Delphi XE5 Professional
 
#4

AW: OleVariant PSafeArray

  Alt 5. Jan 2022, 15:54
Habe gerade das für VB gefunden (soll auch funktionieren):

Dim refKey() As Byte = New Byte() {}
oFeature.GetReferenceKey(refKey)
MsgBox(ThisDoc.Document.ReferenceKeyManager.KeyToS tring(refKey))

kann man das nach Delphi übersetzen?
Bernhard
  Mit Zitat antworten Zitat
Berni68

Registriert seit: 9. Jan 2006
Ort: Villingen
162 Beiträge
 
Delphi XE5 Professional
 
#5

AW: OleVariant PSafeArray

  Alt 7. Jan 2022, 10:57
Hallo,

ich habe nun fogendes herausbekommen:
der OLE-server erwartet ein Array mit 12 Byte.
Die Schnittstelle lässt nur OleVariant zu: (var ReferenceKey: {NOT_OLEAUTO(PSafeArray)}OleVariant; KeyContext: Integer)
der KeyContext ist in diesem Kontext egal.

Ich will jetz ein OleVariant bauen das das 12 Byte array enthält:
Delphi-Quellcode:
function test:OleVariant;
var i: integer;
  Pb: Pointer;
  Vb: OleVariant;
  b: TBytes;
    tsa: TSafeArray;
    psa: PSafeArray;
    tag: TSafeArrayBound;
  P: Pointer;
  V: OleVariant;
begin
  SetLength(b,12); for i:=0 to 11 do b[i]:=0;
  Vb:= VarArrayCreate([0, 12], varByte);
  Pb:= VarArrayLock(Vb);
  Move(b[0], Pb^, 12);
  VarArrayUnlock(Vb);

  tsa.cDims:= 1;
  tsa.fFeatures:= 0001; // <-??   
  tsa.cbElements:= 12;
  tsa.cLocks:= 0001; // <-??
  tsa.pvData:= Pb; ;
    tag.lLbound:= 0;
    tag.cElements:= 12;
    tsa.rgsabound[0]:=tag;
  psa:= @tsa;

  V:= VarArrayCreate([0,0], varDispatch); // nicht: varVariant,varDispatch
  P:= VarArrayLock(V);
  Move(psa, P^, SizeOf(psa));
  VarArrayUnlock(V);

  Result:= V;
end;
wenn ich das nun Aufrufe:

MS.Item[1].GetReferenceKey(test, 0); erhalte ich als Fehlermeldung nicht mehr "Typenkonflikt" sondern
"Variante oder sicheres Array ist gesperrt"
(Zumindest wird die OleVariant mal akzeptiert)

Weiß jemand Rat?
tsa.fFeatures
tsa.cLocks
Bernhard

Geändert von Berni68 ( 7. Jan 2022 um 11:01 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: OleVariant PSafeArray

  Alt 7. Jan 2022, 15:44
Delphi-Referenz durchsuchenSafeArrayCreate ?

aus System.VarUtils (aber gibt es auch nochmal in Winapi.ActiveX und Winapi.Ole2, falls das Eine nicht reicht)




https://www.delphipraxis.net/181879-...safearray.html
https://de.comp.lang.delphi.misc.nar...iant-ubergeben
http://www.delphigroups.info/2/3a/266174.html
...
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Berni68

Registriert seit: 9. Jan 2006
Ort: Villingen
162 Beiträge
 
Delphi XE5 Professional
 
#7

AW: OleVariant PSafeArray

  Alt 9. Jan 2022, 13:03
Hallo himitsu,

danke für den Hinweis.
Hilft mir aber nicht weiter.

Ich interpretiere
Delphi-Quellcode:
    procedure GetReferenceKey(var ReferenceKey: {NOT_OLEAUTO(PSafeArray)}OleVariant;
                              KeyContext: Integer); dispid 2130706454;
analog dazu liefert Free Pascal
// Warning: 'PSafeArray' not automatable in ModelStatedisp.GetReferenceKey nun so, daß das mit Pascal nicht geht und gebe auf.
Bernhard
  Mit Zitat antworten Zitat
peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
672 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: OleVariant PSafeArray

  Alt 10. Jan 2022, 14:35
Hallo himitsu,

danke für den Hinweis.
Hilft mir aber nicht weiter.

Ich interpretiere
Delphi-Quellcode:
    procedure GetReferenceKey(var ReferenceKey: {NOT_OLEAUTO(PSafeArray)}OleVariant;
                              KeyContext: Integer); dispid 2130706454;
analog dazu liefert Free Pascal
// Warning: 'PSafeArray' not automatable in ModelStatedisp.GetReferenceKey nun so, daß das mit Pascal nicht geht und gebe auf.
Liefert der type library import auch ein dual interface neben dem dispinterface? Wenn ja solltest Du lieber das verwenden, da kann man notfalls die generierte Deklaration der Methode anpassen wenn der type library importer das nicht richtig gemacht hat.

Ich hatte mal ein dispinterface, das nicht wirklich automation-kompatible Methoden enthielt. Da half dann sowas:

Delphi-Quellcode:
   {PB 2005-10-07 The VoidPtrToBufID function does not work as declared by the
    type library importer. Removing the Var for the buffer parameter makes it
     work, though. }

    function VoidPtrToBufID({var} buffer: {??Pointer} OleVariant; bufflen: Integer): Integer; dispid 20007;
Verwendung:
Delphi-Quellcode:
{!
<summary>
  CreateSketchFromBuffer is a helper routine, it reads a sketch from
  a memory buffer.</summary>
<returns>
an ISIS sketch handle, or INVALID_ID, if the read failed. The caller
    has to eventually release this handle via the DeleteSketch method of
    the ISIS automation server.</returns>
<param name="pData">
is the buffer's address.</param>
<param name="len">is the length of the data, in bytes.</param>
}

function TIsisMolinfoHelper.CreateSketchFromBuffer(pData: Pointer; Len:
    integer): Integer;
var
  hSketch: Integer;
  V: TVarData;
  BufID: Integer;
begin
  {$IFDEF LOGDETAIL}
  Logmanager.Log('Start - TIsisMolinfoHelper.CreateSketchFromBuffer');
  {$ENDIF}

  Result := INVALID_ID;
  V.VType := VT_PTR;
  V.VPointer := pData;
  {$IFDEF LOGDETAIL}
  Logmanager.Log('TIsisMolinfoHelper.CreateSketchFromBuffer - calling VoidPtrToBufID');
  {$ENDIF}
  BufID := Isis.VoidPtrToBufID(Olevariant(V), Len);
  if BufID > 0 then
    try
      {$IFDEF LOGDETAIL}
      Logmanager.Log('TIsisMolinfoHelper.CreateSketchFromBuffer - calling ReadSketchFromBuffer');
      {$ENDIF}
      hSketch := Isis.ReadSketchFromBuffer(BufID);
      {$IFDEF LOGDETAIL}
      Logmanager.Log('TIsisMolinfoHelper.CreateSketchFromBuffer - ReadSketchFromBuffer returned');
      {$ENDIF}
      if hSketch <> INVALID_ID then
        Result := hSketch
      else begin
        {$IFDEF DEBUG}
        Logmanager.Log('CreateSketchFromBuffer: ReadSketchFromBuffer failed.');
        {$ENDIF}
      end; { Else }
    finally
      isis.DeleteBuffer(BufID);
    end { finally }
  else begin
    {$IFDEF DEBUG}
    Logmanager.Log('CreateSketchFromBuffer: VoidPtrToBufID failed.');
    {$ENDIF}
  end; { Else }
end;
Peter Below
  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 09:45 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