Announcement

Collapse
No announcement yet.

Zugriff auf ein Array einer Typbibliothek

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Zugriff auf ein Array einer Typbibliothek

    Hallo,

    ich habe über Delphi eine typelibrary importiert (interface IUnknown) die z.B. folgende Funktion, die als Ergebnis ein einfaches Array unbekannter Größe/Anzahl mit Zahlenwerten liefern sollte

    z.B.

    1080
    1081,5
    1084
    1085,3
    ...

    hier die funktion:

    <pre>
    function Get_adClose(out pVal: PSafeArray): HResult; stdcall;
    </pre>

    alle funktionen der typelibrary ohne arrays kann ich ohne probleme nutzen (dank COM/DCOM mit Delphi - von Andreas Kosch)- nur leider bekomme ich es nicht auf die Reihe das besagte Array auszulesen.

    Soweit ich herausbekommen habe sind die daten wohl nicht in dem Psafearray selbst gespeichert , sondern das Psafearray liefert nur einen zeiger auf die eigentlichen Daten, aber wie ich jetzt über den zeiger an die daten kommen - hier scheitert leider mein momentanes delphi wissen.

    Kann mir hier vielleicht jemand ein simples Beispiel zum auslesen dieser funktion zeigen

    Im voraus besten Dank für Eure Hilfe

    Ralf

  • #2
    Hallo,

    in der Tat muss zuerst der Zeiger ausgepackt werden. Das folgende Beispiel demonstriert das Prinzip:
    <pre>
    <b>unit</b> PSafeArrayTestFrm;
    <br>
    <b>interface</b>
    <br>
    <b>uses</b>
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    StdCtrls, ActiveX;
    <br>
    <b>type</b>
    TForm1 = <b>class</b>(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    <b>procedure</b> Button1Click(Sender: TObject);
    <b>private</b>
    <font color="#003399"><i>{ Private-Deklarationen }</i></font>
    <b>procedure</b> ShowArrayItems(pValues: PSafeArray);
    <b>procedure</b> ShowVariantArrayItems(aValues : Variant);
    <b>public</b>
    <font color="#003399"><i>{ Public-Deklarationen }</i></font>
    <b>end</b>;
    <br>
    <b>var</b>
    Form1: TForm1;
    <br>
    <b>implementation</b>
    <br>
    <font color="#003399"><i>{$R *.DFM}</i></font>
    <br>
    <b>procedure</b> TForm1.Button1Click(Sender: TObject);
    <b>var</b>
    i : Integer;
    aArray : Variant;
    sTxt : <b>String</b>;
    <b>begin</b>
    aArray := VarArrayCreate([0, 8], varOleStr);
    <b>for</b> i := 0 <b>to</b> 8 <b>do</b> <b>begin</b>
    sTxt := <font color="#9933CC">'Eintrag '</font> + IntToStr(i+1);
    aArray[i] := sTxt;
    <b>end</b>;
    <font color="#003399"><i>// Beide Aufruf führen zum gleichen Ergebnis</i></font>
    ShowArrayItems(PSafeArray(TVarData(aArray).VArray) );
    ListBox1.Items.Add(<font color="#9933CC">'---------------'</font>);
    ShowVariantArrayItems(aArray);
    <b>end</b>;
    <br>
    <b>procedure</b> TForm1.ShowArrayItems(pValues: PSafeArray);
    <b>var</b>
    i : Integer;
    swValue : WideString;
    <b>begin</b>
    <b>for</b> i := 0 <b>to</b> 8 <b>do</b> <b>begin</b>
    SafeArrayGetElement(pValues, i, swValue);
    ListBox1.Items.Add(swValue);
    <b>end</b>;
    <b>end</b>;
    <br>
    <b>procedure</b> TForm1.ShowVariantArrayItems(aValues: Variant);
    <b>var</b>
    i : Integer;
    <b>begin</b>
    <b>for</b> i := 0 <b>to</b> 8 <b>do</b>
    ListBox1.Items.Add(aValues[i]);
    <b>end</b>;
    <br>
    <b>end</b>.
    </pre>
    Über <b>SafeArrayGetDim</b> und <b>SafeArrayGetLBound</b> etc. kann man vorher nachschauen, wie viele Elemente ausgepackt werden müssen:
    <pre>
    <b>procedure</b> TFormMain.ButtonInfoClick(Sender: TObject);
    <b>var</b>
    pSA : PSafeArray;
    i : Integer;
    swValue : WideString;
    iDim : Integer;
    iLBound : Integer;
    iUBound : Integer;
    <b>begin</b>
    pSA := <b>nil</b>;
    FSrv.GetInfos(pSA);
    iDim := SafeArrayGetDim(pSA);
    <b>if</b> iDim = 1 <b>then</b>
    <b>begin</b>
    SafeArrayGetLBound(pSA, 1, iLBound);
    SafeArrayGetUBound(pSA, 1, iUBound);
    <b>for</b> i := iLBound <b>to</b> iUBound <b>do</b>
    <b>begin</b>
    SafeArrayGetElement(pSA, i, swValue);
    ListBox1.Items.Add(swValue);
    <b>end</b>;
    <b>end</b>;
    SafeArrayDestroy(pSA);
    <b>end</b>;
    </pre&gt

    Comment


    • #3
      Hallo,

      super ! vielen Dank - der folgende code führt genau zum gewünschten ergebnis (das problem hat mich die letzten 3wochen ganz schön beschäftigt)

      Eine letzte frage noch in der delphi hilfe findet man nichts zu safearraygetlbound, savearraygetelement, etc. wo kann ich denn noch nähere informationen zu diesen funktionen finden ? bzw. Fsrv.Getinfos(pSA) kann ich nicht ohne fehler einbinden, was aber die funktion des codes nicht zu beinträchtigen scheint

      Auf jedenfall hat mich dieses Bsp um Jahre nach vorne gebracht - jetzt kann ich endlich anfangen meine ideen in code umzusetzen

      Nochmals Danke

      Ralf

      <pre>
      var
      pSA : PSafeArray;
      i : Integer;
      swValue : single; //geändert von widestring
      iDim : Integer;
      iLBound : Integer;
      iUBound : Integer;
      begin
      pSA := nil;

      // Verbindung zur Typbibliothek
      iquotes:= coMLInternetquotes.Create; // 2. coclasse definieren
      iquotes.DownloadHistoricalQuotes('SUNW',20041013,2 0050114,d);
      // PSaveArray abfragen
      // Typbibliothek: function Get_adClose(out pVal: PSafeArray): HResult; stdcall;
      iquotes.Get_adClose(pSa);

      //FSrv.GetInfos(pSA);
      iDim := SafeArrayGetDim(pSA);
      if iDim = 1 then
      begin
      SafeArrayGetLBound(pSA, 1, iLBound);
      SafeArrayGetUBound(pSA, 1, iUBound);
      for i := iLBound to iUBound do
      begin
      SafeArrayGetElement(pSA, i, swValue);
      ListBox1.Items.Add(floattostr(swValue));
      end;
      end;
      SafeArrayDestroy(pSA);
      end;
      </pre&gt

      Comment


      • #4
        Hallo,

        &gt;..Fsrv.Getinfos(pSA) kann ich nicht ohne fehler einbinden...

        dahinter steckt der COM-Server, der seine Daten in einem SafeArray verpackt und als PSafeArray zum Client zurückschickt.

        &gt;..in der delphi hilfe findet man nichts zu safearraygetlbound...

        Es handelt sich um Win32-API-Funktionen, die von Microsoft in den Hilfedateien des <i>Microsoft Platform SDK</i> (über 100 MByte Hilfe) dokumentiert werden. Dort taucht die Beschreibung im Abschnitt <i>Component Service | COM | Conversion and Manipulation Functions | Array Manipulation API Functions</i> auf. Die Delphi-Hilfe beschreibt generell nur die Funktionen, die Borland zusätzlich zum Win32-API zur Verfügung stellt

        Comment


        • #5
          Hallo,

          &gt;..Fsrv.Getinfos(pSA) kann ich nicht ohne fehler einbinden...

          dahinter steckt der COM-Server, der seine Daten in einem SafeArray verpackt und als PSafeArray zum Client zurückschickt.

          &gt;..in der delphi hilfe findet man nichts zu safearraygetlbound...

          Es handelt sich um Win32-API-Funktionen, die von Microsoft in den Hilfedateien des <i>Microsoft Platform SDK</i> (über 100 MByte Hilfe) dokumentiert werden. Dort taucht die Beschreibung im Abschnitt <i>Component Service | COM | Conversion and Manipulation Functions | Array Manipulation API Functions</i> auf. Die Delphi-Hilfe beschreibt generell nur die Funktionen, die Borland zusätzlich zum Win32-API zur Verfügung stellt.

          Siehe beigefügte Abbildung

          Comment

          Working...
          X