Announcement

Collapse
No announcement yet.

Problem: Dynamisches Laden einer DLL

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

  • Problem: Dynamisches Laden einer DLL

    Hallo Delphi-Gemeinde,

    ich rufe aus einer Delphi-DLL, die dynamisch ge- und entladen wird, über eine ActiveX-Komponente eine SAP-System auf.

    <B>Problem:</B>
    wenn ich nach dem Aufruf des SAP-System die DLL entlade (FreeLibrary..), wir auch automatisch das SAP-System geschlossen. Wird die DLL nicht nach dem Aufruf entladen, dann gibt es beim 2. Aufruf des SAP-System einen Fehler.

    Also: was kann man tun. Hat von Euch vielleicht einer eine Idee?

    Vielen Dank und schöne Grüße
    Thorsten

  • #2
    Hallo,

    wenn die dynamisch geladene DLL einen Interface-Zeiger auf ein COM-Objekt (ActiveX) anfordert, so "lebt" diese COM-Objektinstanz nur so lange, bis der letzte Client seinen letzten Interface-Zeiger auf diese Instanz freigibt. Sobald der "Verwendungszähler" der Interface-Variable auf 0 steht, wird die ActiveX-Instanz entsorgt. Somit entspricht das geschilderte Verhalten dem Standardverhalten von COM.

    &gt;Wird die DLL nicht nach dem Aufruf entladen, <br>
    &gt;dann gibt es beim 2. Aufruf des SAP-System einen Fehler.

    Das ist <b>kein</b> Standardverhalten, sondern muss entweder mit den "Innereien" der DLL oder des ActiveX zusammenhängen. Was sagt die Dokumentation dieses ActiveX an dieser Stelle? Wie sieht der Aufruf in der DLL konkret aus? Welcher Fehler wird zurückgeliefert

    Comment


    • #3
      Hallo Andreas,

      erst einmal vielen Dank für Deine schnelle Antwort.<P>

      Vielleicht hier noch einmal eine etwas detaillierte Beschreibung des Problems.<P>

      Also: aus einer externen Nicht-Delphi-Anwendung werden über eine Delphi-DLL Informationen/Daten an Excel übergeben. In Excel werden dann die Daten kalkuliert und das Ergebnis der Kalkulation wird wieder über die DLL an die externe Anwendung zurückgegeben.<BR>

      Die DLL wird dabei dynamisch geladen ( <B>LoadLibrary(...)</B> ). Wenn die externe Anwendung wieder beendet wird, wird dann auch die DLL entladen.<BR>

      Für den Datenaustausch werden die Standard-Delphi-Komponenten <I>TExcelWorkSheet</I>, <I>TExcelWorkBook</I> und <I>TExcelApplication</I> verwendet.<P>

      <B>Jetzt das eigentlich Problem:</B><BR>
      Nach der Datenübertragung soll Excel noch sichtbar sein! Das ist nicht das Problem. Allerdings kann dann natürlich auch kein <B>Disconnect</B> erfolgen. Dann ist Excel nicht mehr sichtbar. Deshalb bleiben die o.g. Excel-Komponenten noch im Speicher. Wenn der Anwender nun Excel geschlossen hat, und möchte z.B. manuell das Dokument noch einmal öffnen, dann hängt sich Excel auf (im TaskManager ist noch ein Task EXCEL.EXE zu sehen). Erst wenn dann der Task ?<I>abgeschossen</I>? wird, oder die externe Anwendung beendet wird, kann dieses Dokument auch wieder geöffnet werden, ohne das Excel abstürzt.<P>

      Normalerweise muss nach der Datenübertragung ein Disconnect der o.g. Komponenten erfolgen. Da aber das hat dann zur Folge, das auch Excel geschlossen wird. Und Excel soll aber für den Anwender noch sichtbar sein.<P>

      Ich hoffe ich konnte das Problem einigermaßen verständlich beschreiben. Hast Du vielleicht noch eine Idee, wie man das Problem lösen kann???

      Schönen Gruß<BR>
      Thorste

      Comment


      • #4
        So auf die schnelle, falls alles nichts hilft, dann öffne Exel über deine Komponenten, führe die Berechnungen durch, speichere diese Datei und disconnecte. Danach öffnest du die neue Datei über ShellExecute().

        Gruß Hage

        Comment


        • #5
          Hallo,

          in der originalen Frage war von einer ActiveX-Komponente (DLL) die Rede, aber im Fall eines Local Servers (EXE von Excel) hat man deutlich mehr Alternativen:

          1. Die DLL ruft beim ersten Zugriff die Win32-API-Funktion <b>CoAddRefServerProcess</b> auf, um den COM-Server von Excel zu sperren (d.h. die Referenzzählung des Interface-Zeigers wird außer Kraft gesetzt). Erst dann, wenn das Programm den Automation-Server von Excel nicht mehr benötigt, wird die Sperre über die Win32-API-Funktion <b>CoReleaseServerProcess</b> wieder entfernt.

          2. Der Automation-Server von Microsoft Excel hat die Besonderheit, dass die Eigenschaft <b>UserControl</b> explizit entsprechend den Anforderungen bedient werden muss. Wenn der Anwender parallel zum Automation-Zugriff weiterhin mit Excel arbeiten soll, ist folgendes notwendig:
          <pre>
          <b>procedure</b> TForm1.Button_1Click(Sender: TObject);
          <b>begin</b>
          FLCID := GetUserDefaultLCID;
          ExcelApplication1.Connect;
          ExcelApplication1.Visible[FLCID] := True;
          ExcelApplication1.UserControl := True;
          <b>end</b>;
          </pre>

          3. Der Automation-Server von Microsoft Excel hat die Besonderheit, dass er die Interface-Methode <b>Quit</b> erwartet, wenn die vollständige Anwendung geschlossen werden soll. Wenn ein Client nach der Automation die Anwendung vollständig abräumen will, ist der folgende Beispiel-Aufruf geeignet (erst nach dem Aufruf der Interface-Methode Quit wird die Automation-Verbindung getrennt:
          <pre>
          <b>procedure</b> TForm1.Button_6Click(Sender: TObject);
          <b>begin</b>
          ExcelWorksheet1.Disconnect;
          <font color="#003399"><i>// Workbook ohne Speichern schliessen</i></font>
          ExcelWorkbook1.Close(False);
          ExcelWorkbook1.Disconnect;
          <font color="#003399"><i>// Excel beenden</i></font>
          ExcelApplication1.Quit;
          ExcelApplication1.Disconnect;
          <b>end</b>;
          </pre>
          Wenn Quit <b>nicht</b> aufgerufen wird und die Eigenschaft <b>UserControl</b> auf True steht, sollte die Benutzeroberfläche von Excel auch nach dem Freigeben des letzten Interface-Zeigers noch bedienbar sein.
          &#10

          Comment


          • #6
            Hallo Hagen,

            vielen Dank für Deinen Tipp. Habe von Andreas noch einen vielversprechenden Hinweis bekommen. Dem werde ich erst einmal nachgehen. Wenn alle Stricke reißen, werde ich es mit ShellExecute probieren. Das wird auf jeden Fall funktionieren.<P>

            Danke und nen schönen Grüß.<BR>
            Thorste

            Comment


            • #7
              Hallo Andreas,

              das hört sich gut an, und könnte mein Problem lösen.<BR>
              Ich werde es auf jeden Fall ausprobieren!!!<P>

              Vielen Dank für Deine Hilfe.<BR>
              Schöne Grüße<BR>
              Thorste

              Comment

              Working...
              X