Announcement

Collapse
No announcement yet.

No Mapping for Dispatch Mode

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

  • No Mapping for Dispatch Mode

    Hallo<BR>
    Beim Aufruf einer Methode eines COM-Objekts (kein eigenes) bekomme ich die Meldung "No Mapping for Dispatch Mode". <BR><BR>Weiß jemand was das zu bedeuten hat ??<BR><BR>
    Danke.

  • #2
    Hallo,
    <br><br>
    COM unterstützt 3 verschiedene Arten der Bindung:
    <br><br>
    1. Späte Bindung (das aufrufende Programm "fragt" über IDispatch.GetIDsOfNames beim aufgerufenen Objekt nach, welcher Token-Wert (DispID) für einen Eigenschafts- oder Methodensnamen gültig ist. Liegt der numerische Wert des Tokens vor, kann das Programm die gewünschte Eigenschaft oder Funktion über den Aufruf von IDispatch.Invoke ansprechen)
    <br><br>
    2. Frühe Bindung (das aufrufende Programm greift direkt über eine Offset-Adresse auf die Methode zu).
    <br><br>
    3. DispID-Bindung (eine Abkürzung der späten Bindung, bei der sofort die IDispatch-Methode Invoke über eine feststehende DispID aufgerufen wird).
    <br><br>
    Die Fehlermeldung deutet darauf hin, dass der direkte DispID-Aufruf nicht korrekt ist. Wie sieht der konkrete Aufruf im Detail aus? Was zeigt die importierte Typbibliothek an dieser Stelle an (siehe nachfolgendes Beispiel)?
    <pre>
    _ApplicationDisp = dispinterface
    [<font color="#9933CC">'{00020970-0000-0000-C000-000000000046}'</font>]
    <b>property</b> Application: Application readonly dispid 1000;
    <b>property</b> Creator: Integer readonly dispid 1001;
    <b>property</b> Parent: IDispatch readonly dispid 1002;
    <b>property</b> Name: WideString readonly dispid 0;
    <b>property</b> Documents: Documents readonly dispid 6;
    ...
    </pre&gt

    Comment


    • #3
      Hallo Herr Kosch.<BR><BR>
      Vielen Dank für Ihre Antwort. Die Typbibliothek sieht folgendermaßen aus (kleiner Auszug):<BR><BR>
      // ************************************************** *******************//<BR>
      // Forward-Deklaration von in der Typbibliothek definierten Typen<BR>
      // ************************************************** *******************//<BR>
      IOrderRequest = interface;<BR>
      IOrderRequestDisp = dispinterface;<BR>

      // ************************************************** *******************//<BR>
      // Deklaration von in der Typbibliothek definierten CoClasses<BR>
      ************************************************** *******************//<BR>
      SilentCommerce = IUnknown;<BR>
      // ************************************************** *******************//<BR>
      // Deklaration von Strukturen, Unions und Aliasen.<BR>
      // ************************************************** *******************//
      TUserData_SC = packed record<BR>
      sSalesOrgId: WideString;<BR>
      sUserId: WideString;<BR>
      sPassword: WideString;<BR>
      sLanguage: WideString;<BR>
      end;<BR>

      TOrderHeaderInfo_SC = packed record<BR>
      sSupplierNumber: WideString;<BR>
      sPurchaseNumber: WideString;<BR>
      sCurrency: WideString;<BR>
      nCompleteDelivery: Integer;<BR>
      sDispatchMode: WideString;<BR>
      sDeliveryDate: WideString;<BR>
      sInquiryNumber: WideString;<BR>
      end;<BR>
      TOrder_SC = packed record<BR>
      eOrderType: <BR>__MIDL___MIDL_itf_SilentCommerce_0000_0001;<BR >
      xHeaderInfo: TOrderHeaderInfo_SC;<BR>
      nShipToExists: Integer;<BR>
      xShipTo: TCustomer_SC;<BR>
      nBillToExists: Integer;<BR>
      xBillTo: TCustomer_SC;<BR>
      nNumberOfItems: Integer;<BR>
      xOrderItems: PSafeArray;<BR>
      end;<BR>

      TMaterial_SC = packed record<BR>
      sNumberSystem: WideString;<BR>
      sMaterial: WideString;<BR>
      sEan: WideString;<BR>
      end;<BR>

      TOrderItem_SC = packed record<BR>
      nPositionItem: Integer;<BR>
      xMaterial: TMaterial_SC;<BR>
      sShortText: WideString;<BR>
      nRequestedQuantity: Integer;<BR>
      sQuantityUnit: WideString;<BR>
      nPartialDelivery: Integer;<BR>
      nAlternativeMaterialAllowed: Integer;<BR>
      nBackOrderAllowed: Integer;<BR>
      sDeliveryDate: WideString;<BR>
      end;<BR>

      TROrder_SC = packed record<BR>
      sDocumentNumber: WideString;<BR>
      sTeccomDocumentId: WideString;<BR>
      nNumberOfHeaderResponses: Integer;<BR>
      xHeaderResponses: PSafeArray;<BR>
      nNumberOfROrderItems: Integer;<BR>
      xROrderItems: PSafeArray;<BR>
      end;<BR>

      TResponse_SC = packed record<BR>
      nResponseClass: Integer;<BR>
      nResponseType: Integer;<BR>
      nResponseNumber: Integer;<BR>
      sResponseText: WideString;<BR>
      sResponseParameter: WideString;<BR>
      end;<BR>
      // ************************************************** *******************//<BR>
      // Schnittstelle: IOrderRequest<BR>
      // Flags: (4416) Dual OleAutomation Dispatchable<BR>
      // GUID: {60F59E8A-2151-4F1C-B40E-3DDF01B8AF97}<BR>
      // ************************************************** *******************//<BR>
      IOrderRequest = interface(IDispatch)<BR>
      ['{60F59E8A-2151-4F1C-B40E-3DDF01B8AF97}']<BR>
      procedure SendOrder(var xUserData: TUserData_SC; var xOrder: TOrder_SC;
      var xOrderResponse: TROrder_SC; var sLoggingInfo: WideString); safecall;<BR>
      end;<BR>

      // ************************************************** *******************//<BR>
      // DispIntf: IOrderRequestDisp<BR>
      // Flags: (4416) Dual OleAutomation Dispatchable<BR>
      // GUID: {60F59E8A-2151-4F1C-B40E-3DDF01B8AF97}<BR>
      // ************************************************** *******************//<BR>
      IOrderRequestDisp = dispinterface<BR>
      ['{60F59E8A-2151-4F1C-B40E-3DDF01B8AF97}']<BR>
      procedure SendOrder(var xUserData: {??TUserData_SC}OleVariant;
      var xOrder: {??TOrder_SC}OleVariant;
      var xOrderResponse: {??TROrder_SC}OleVariant; var sLoggingInfo: WideString); dispid 1;<BR>
      end;<BR><BR><BR>
      1. Versuch SenderOrder auszuführen mit dem Ergebnis "Falscher Parameter"<BR>
      var<BR>
      FOrderRequest: IOrderRequest<BR>
      xUserData: TUserData_SC<BR>
      xOrder: TOrder_SC<BR>
      xHeaderInfo: TOrderHeaderInfo_SC<BR>
      xOrderItems: TOrderItem_SC<BR>
      xMaterial: TMaterial_SC<BR>
      xOrderResponse: TROrder_SC<BR>
      sLoggingInfo: WideString<BR>
      aOrderItem_SC: Array[0..1] of TOrderItem_SC<BR>
      vOrderItem_SC: Variant<BR>
      vRecordInfo: IRecordInfo<BR>
      pOrderItem_SC: Pointer<BR>
      psOrderItem_SC: PSafeArray<BR>
      begin<BR>
      FOrderRequest := CreateOleObject('SilentCommerce.OrderRequest') as IOrderRequest<BR><BR>
      xUserData.sSalesOrgId := ''<BR>
      xUserData.sUserId := ''<BR>
      xUserData.sPassword := ''<BR>
      xUserData.sLanguage := 'DE'<BR><VR>
      xHeaderInfo.sSupplierNumber := '4711'<BR>
      xHeaderInfo.sPurchaseNumber := '4711'<BR>
      xHeaderInfo.sCurrency := 'EUR'<BR>
      xHeaderInfo.nCompleteDelivery := 1<BR><BR>
      xMaterial.sMaterial := 'Artikel1'<BR>
      aOrderItem_SC[0].nPositionItem := 1<BR>
      aOrderItem_SC[0].xMaterial := xMaterial<BR><BR>
      xMaterial.sMaterial := 'Artikel2'<BR>
      aOrderItem_SC[1].nPositionItem := 2<BR>
      aOrderItem_SC[1].xMaterial := xMaterial<BR><BR>
      //iid_OrderItem TGUID = '{EE852156-C805-48A8-BD85-87E5C790FB3E}'<BR>
      vRecordInfo := GetStructRecordInfo(iid_OrderItem, LIBID_SilentCommerceLib)<BR><BR>
      vOrderItem_SC := VarArrayCreateEx([0,1], VT_RECORD, vRecordInfo)<BR>
      pOrderItem_SC := VarArrayLock(vOrderItem_SC)<BR><BR>
      //TRec = array of TOrderItem_SC<BR>
      TRec(pOrderItem_SC)[0].xMaterial := aOrderItem_SC[0].xMaterial<BR>
      TRec(pOrderItem_SC)[0].nPositionItem := 1<BR>
      TRec(POrderItem_SC)[1].xMaterial := aOrderItem_SC[1].xMaterial<BR>
      TRec(POrderItem_SC)[1].nPositionItem := 2<BR><BR>
      VarArrayUnlock(vOrderItem_SC)<BR><BR>
      psOrderItem_SC := PSafeArray(TVarData(vOrderItem_SC).VArray)<BR><BR>
      xOrder.eOrderType := 0<BR>
      xOrder.xHeaderInfo := xHeaderInfo<BR>
      xOrder.nShipToExists := 0<BR>
      xOrder.nBillToExists := 0<BR>
      xOrder.nNumberOfItems := 2<BR>
      xOrder.xOrderItems := psOrderItem_SC<BR><BR>
      FOrderRequest.SendOrder(xUserData , xOrder , xOrderResponse , sLoggingInfo)<BR>

      &#10

      Comment


      • #4
        Hallo Herr Kosch.<BR><BR>
        Vielen Dank für Ihre Antwort. Ich habe einen Auszug der Typbibliothek bzw. die unterschiedlichen Versuche (mit Hilfe von OsUDFExt.pas) aufgeführt:<BR><BR>
        // ************************************************** *******************//<BR>
        // Forward-Deklaration von in der Typbibliothek definierten Typen<BR>
        // ************************************************** *******************//<BR>
        IOrderRequest = interface;<BR>
        IOrderRequestDisp = dispinterface;<BR>

        // ************************************************** *******************//<BR>
        // Deklaration von in der Typbibliothek definierten CoClasses<BR>
        ************************************************** *******************//<BR>
        SilentCommerce = IUnknown;<BR>
        // ************************************************** *******************//<BR>
        // Deklaration von Strukturen, Unions und Aliasen.<BR>
        // ************************************************** *******************//
        TUserData_SC = packed record<BR>
        sSalesOrgId: WideString;<BR>
        sUserId: WideString;<BR>
        sPassword: WideString;<BR>
        sLanguage: WideString;<BR>
        end;<BR>

        TOrderHeaderInfo_SC = packed record<BR>
        sSupplierNumber: WideString;<BR>
        sPurchaseNumber: WideString;<BR>
        sCurrency: WideString;<BR>
        nCompleteDelivery: Integer;<BR>
        sDispatchMode: WideString;<BR>
        sDeliveryDate: WideString;<BR>
        sInquiryNumber: WideString;<BR>
        end;<BR>
        TOrder_SC = packed record<BR>
        eOrderType: <BR>__MIDL___MIDL_itf_SilentCommerce_0000_0001;<BR >
        xHeaderInfo: TOrderHeaderInfo_SC;<BR>
        nShipToExists: Integer;<BR>
        xShipTo: TCustomer_SC;<BR>
        nBillToExists: Integer;<BR>
        xBillTo: TCustomer_SC;<BR>
        nNumberOfItems: Integer;<BR>
        xOrderItems: PSafeArray;<BR>
        end;<BR>

        TMaterial_SC = packed record<BR>
        sNumberSystem: WideString;<BR>
        sMaterial: WideString;<BR>
        sEan: WideString;<BR>
        end;<BR>

        TOrderItem_SC = packed record<BR>
        nPositionItem: Integer;<BR>
        xMaterial: TMaterial_SC;<BR>
        sShortText: WideString;<BR>
        nRequestedQuantity: Integer;<BR>
        sQuantityUnit: WideString;<BR>
        nPartialDelivery: Integer;<BR>
        nAlternativeMaterialAllowed: Integer;<BR>
        nBackOrderAllowed: Integer;<BR>
        sDeliveryDate: WideString;<BR>
        end;<BR>

        TROrder_SC = packed record<BR>
        sDocumentNumber: WideString;<BR>
        sTeccomDocumentId: WideString;<BR>
        nNumberOfHeaderResponses: Integer;<BR>
        xHeaderResponses: PSafeArray;<BR>
        nNumberOfROrderItems: Integer;<BR>
        xROrderItems: PSafeArray;<BR>
        end;<BR>

        TResponse_SC = packed record<BR>
        nResponseClass: Integer;<BR>
        nResponseType: Integer;<BR>
        nResponseNumber: Integer;<BR>
        sResponseText: WideString;<BR>
        sResponseParameter: WideString;<BR>
        end;<BR>
        // ************************************************** *******************//<BR>
        // Schnittstelle: IOrderRequest<BR>
        // Flags: (4416) Dual OleAutomation Dispatchable<BR>
        // GUID: {60F59E8A-2151-4F1C-B40E-3DDF01B8AF97}<BR>
        // ************************************************** *******************//<BR>
        IOrderRequest = interface(IDispatch)<BR>
        ['{60F59E8A-2151-4F1C-B40E-3DDF01B8AF97}']<BR>
        procedure SendOrder(var xUserData: TUserData_SC; var xOrder: TOrder_SC;
        var xOrderResponse: TROrder_SC; var sLoggingInfo: WideString); safecall;<BR>
        end;<BR>

        // ************************************************** *******************//<BR>
        // DispIntf: IOrderRequestDisp<BR>
        // Flags: (4416) Dual OleAutomation Dispatchable<BR>
        // GUID: {60F59E8A-2151-4F1C-B40E-3DDF01B8AF97}<BR>
        // ************************************************** *******************//<BR>
        IOrderRequestDisp = dispinterface<BR>
        ['{60F59E8A-2151-4F1C-B40E-3DDF01B8AF97}']<BR>
        procedure SendOrder(var xUserData: {??TUserData_SC}OleVariant;
        var xOrder: {??TOrder_SC}OleVariant;
        var xOrderResponse: {??TROrder_SC}OleVariant; var sLoggingInfo: WideString); dispid 1;<BR>
        end;<BR><BR><BR>
        1. Versuch SenderOrder auszuführen mit dem Ergebnis "Falscher Parameter"<BR>
        var<BR>
        FOrderRequest: IOrderRequest<BR>
        xUserData: TUserData_SC<BR>
        xOrder: TOrder_SC<BR>
        xHeaderInfo: TOrderHeaderInfo_SC<BR>
        xOrderItems: TOrderItem_SC<BR>
        xMaterial: TMaterial_SC<BR>
        xOrderResponse: TROrder_SC<BR>
        sLoggingInfo: WideString<BR>
        aOrderItem_SC: Array[0..1] of TOrderItem_SC<BR>
        vOrderItem_SC: Variant<BR>
        vRecordInfo: IRecordInfo<BR>
        pOrderItem_SC: Pointer<BR>
        psOrderItem_SC: PSafeArray<BR>
        begin<BR>
        FOrderRequest := CreateOleObject('SilentCommerce.OrderRequest') as IOrderRequest<BR><BR>
        xUserData.sSalesOrgId := ''<BR>
        xUserData.sUserId := ''<BR>
        xUserData.sPassword := ''<BR>
        xUserData.sLanguage := 'DE'<BR><VR>
        xHeaderInfo.sSupplierNumber := '4711'<BR>
        xHeaderInfo.sPurchaseNumber := '4711'<BR>
        xHeaderInfo.sCurrency := 'EUR'<BR>
        xHeaderInfo.nCompleteDelivery := 1<BR><BR>
        xMaterial.sMaterial := 'Artikel1'<BR>
        aOrderItem_SC[0].nPositionItem := 1<BR>
        aOrderItem_SC[0].xMaterial := xMaterial<BR><BR>
        xMaterial.sMaterial := 'Artikel2'<BR>
        aOrderItem_SC[1].nPositionItem := 2<BR>
        aOrderItem_SC[1].xMaterial := xMaterial<BR><BR>
        //iid_OrderItem TGUID = '{EE852156-C805-48A8-BD85-87E5C790FB3E}'<BR>
        vRecordInfo := GetStructRecordInfo(iid_OrderItem, LIBID_SilentCommerceLib)<BR><BR>
        vOrderItem_SC := VarArrayCreateEx([0,1], VT_RECORD, vRecordInfo)<BR>
        pOrderItem_SC := VarArrayLock(vOrderItem_SC)<BR><BR>
        //TRec = array of TOrderItem_SC<BR>
        TRec(pOrderItem_SC)[0].xMaterial := aOrderItem_SC[0].xMaterial<BR>
        TRec(pOrderItem_SC)[0].nPositionItem := 1<BR>
        TRec(POrderItem_SC)[1].xMaterial := aOrderItem_SC[1].xMaterial<BR>
        TRec(POrderItem_SC)[1].nPositionItem := 2<BR><BR>
        VarArrayUnlock(vOrderItem_SC)<BR><BR>
        psOrderItem_SC := PSafeArray(TVarData(vOrderItem_SC).VArray)<BR><BR>
        xOrder.eOrderType := 0<BR>
        xOrder.xHeaderInfo := xHeaderInfo<BR>
        xOrder.nShipToExists := 0<BR>
        xOrder.nBillToExists := 0<BR>
        xOrder.nNumberOfItems := 2<BR>
        xOrder.xOrderItems := psOrderItem_SC<BR><BR>
        FOrderRequest.SendOrder(xUserData , xOrder , xOrderResponse , sLoggingInfo)<BR><BR><BR>
        2. Versuch. Bin beim übergeben der Parameter gescheitert.<BR><BR>
        pDisp := CreateOleObject('SilentCommerce.OrderRequest') as IOrderRequest;<BR>
        sPropName := 'SendOrder';<BR>
        OleCheck(pDisp.GetIDsOfNames (GUID_NULL, @sPropName, 1,
        LOCALE_SYSTEM_DEFAULT, @iDispId));<BR><BR>
        Habe vSet die einzelnen Record (s. oben) in Variant gewandelt und eine OleVariant zugewiesen(VarArrayCreate([0,3], varVariant))<BR><BR>
        vSet := True;<BR>
        FillChar(aDispParams, SizeOf (aDispParams), 0);<BR>
        with aDispParams do begin<BR>
        rgvarg := @vSet;<BR>
        cArgs := 4;<BR>
        cNamedArgs := 1;<BR>
        end;<BR>
        aDispId := DISPID_PROPERTYPUT;<BR>
        aDispParams.rgdispidNamedArgs := @aDispId;<BR>
        OleCheck (pDisp.Invoke (iDispId, GUID_NULL, LOCALE_SYSTEM_DEFAULT,
        DISPATCH_PROPERTYPUT, aDispParams, NIL, @aEI, @iError));<BR><BR><BR>
        3. Versuch mit der Meldung "No Mapping for Dispatch Mode". Wie unter 1 jedoch wurden die Variablen xMaterial und xHeaderInfo nach yMaterial und yHeaderInfo umbenannt. ??????<BR><BR>
        Ich komme jedenfalls keinen Schritt weiter. Wäre dankbar für eine Lösung dieses Problems.<BR><BR>
        Dank

        Comment


        • #5
          Hallo,

          der Zugriff über die späte Bindung kann nicht Funktionieren, weil Delphi beim Importieren der TLB bei den User Defined Types das Handtuch geworfen hat:
          <pre>
          <b>procedure</b> SendOrder(<b>var</b> xUserData: <font color="#003399"><i>{??TUserData_SC}</i></font>OleVariant;
          <b>var</b> xOrder: <font color="#003399"><i>{??TOrder_SC}</i></font>OleVariant;
          <b>var</b> xOrderResponse: <font color="#003399"><i>{??TROrder_SC}</i></font>OleVariant;
          <b>var</b> sLoggingInfo: WideString); dispid 1;
          </pre>
          Man kann zwar auch in Delphi auf UDTs zurückgreifen, aber dann darf der COM-Server allerdings <b>kein</b> Dual-Interface verwenden (d.h. diese Option wird auf der Registerseite <i>Flags</i> in der TLB abgewählt). Nur der Zugriff über die frühe Bindung (VTable) ist in diesem Fall erlaubt.

          In der importierten TLB-Unit sieht das dann so aus: <br>

          a) falsch: // Flags: (4416) Dual OleAutomation Dispatchable

          b) richtig: // Flags: (4352) OleAutomation Dispatchabl

          Comment


          • #6
            Hallo.<BR>Danke für die Antwort<BR>
            Dual-Flag habe ich herausgenommen. <BR><BR>
            Habe anschließend die SendOrder aufgerufen <B>ohne</B> die Records zu füllen.<BR>Es kam die Meldung das der Username bzw. Passwort falsch ist. Soweit alles in Ordnung.<BR>Anschließend habe ich Userdaten dem Record xUserdata Feld1 und Feld2 Werte zugeordnet. Bis dahin war auch alles in Ordnung. Als ich dann die restl. 2 Felder gefüllt habe, bekam die Fehlermeldung "No Mapping for Dispatch Mode".<BR><br>Woran kann das schon wieder liegen

            Comment


            • #7
              Hallo,

              in der importierten TLB-Unit besteht TUserData_SC aus 4 WideString-Feldern. Werden diese Felder auch mit WideStrings befüllt

              Comment


              • #8
                Hallo Herr Kosch.<BR><BR>

                Ich habe nun vom Hersteller des COM-Objekts herausgefunden das die Meldung <B>"No Mapping for Dispatch Mode"</B> überhaupt nichts mit COM zu tun hat.<BR><BR>Die Meldung bedeutet lediglich das die <B>"Versandart"</B> fehlt. <BR>Da muss man erst einmal drauf kommen.<BR><BR>Ich werde nun alle Records mit Werten füllen und warte mal ab was dann passiert. <BR><BR>Ich bedanke mich recht herzlich für Ihre Unterstütung und hoffe das keine weiteren Probleme vorkommen

                Comment


                • #9
                  Hallo<BR>
                  Ich habe ein Problem Werte aus einem PSafeArray auszulesen.<BR><BR>Das COM-Objekt übergibt mir ein Record welcher ein PSafeArray beinhaltet. PSafeArray Lese ich wie folgt aus:<BR><BR>
                  var<BR>
                  po: Pointer;<BR>
                  i, iDim, iLBound, iUBound: Integer;<BR>
                  begin<BR>
                  po := xOrderResponse.xROrderItems //xROrderItems = PSafeArray<BR>
                  iDim := SafeArrayGetDim(po);<BR>
                  if iDim = 1 then<BR>
                  begin<BR>
                  SafeArrayGetLBound(po, 1, iLBound);<BR>
                  SafeArrayGetUBound(po, 1, iUBound);<BR>
                  for i := iLBound to iUBound do<BR>
                  begin<BR>
                  SafeArrayGetElement(po, i, xROrderItem_SC);<BR>
                  ...<BR>
                  end;<BR><BR>
                  Beim ersten Durchlauf (i=0) werden die Werte korrekt ausgelesen. Ist i > 0 bekomme ich die Meldung "Allgemeine Zugriffsverletztung ... in Modul OleOut32.dll"<BR><BR>
                  Gibt es einen anderen Weg ein PSafeArray auszulesen ?<BR&gt

                  Comment


                  • #10
                    Hallo,

                    der Client kann aus einem SafeArray nur dann die Daten fehlerfrei auslesen, wenn auch der Server das SafeArray korrekt befüllt hat. Das folgende Beispiel demonstriert dies:
                    <pre>
                    <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>;
                    ShowArrayItems(PSafeArray(TVarData(aArray).VArray) );
                    <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>;
                    </pre>
                    Steht allerdings die Anzahl der Elemente im SafeArray nicht fest, muß der Aufruf von SafeArrayGetElement durch <b>SafeArrayGetUBound</b> ersetzt werden. Anschließend wird der Endwert für die FOR-Schleife durch den von SafeArrayGetUBound ermittelten Wert für die Anzahl der Einträge im SafeArray ersetzt:
                    <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

                    Working...
                    X