Announcement

Collapse
No announcement yet.

Form in DLL aufrufen

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

  • Form in DLL aufrufen

    Hallo,
    ich habe ein Programm geschrieben, das ich jetzt in eine DLL umwandeln möchte.<br> Beim Aufrufen/Erstellen der ersten Form ( form1:=TForm1.create(Application); ) der DLL kommt aber schon folgende Fehlermeldung:<br> Exception der Klasse EOleSysError: CoInitialize wurde nicht aufgerufen.<p>
    Für jede Hilfe wäre ich dankbar.
    Frank Deters

  • #2
    Hallo,

    Windows legt immer dann mit dieser Fehlermeldung sein Veto ein, wenn ein Prozess über einen Interface-Zeiger auf ein COM-Objekt zugreift, ohne selbst ein eigenes Apartment über den Aufruf von CoInitialize bzw. CoInitializeEx definiert zu haben.

    In einem normalen Delphi 5-Projekt ist die Zeile <i>Application.Initialize</i> in der DPR-Datei dafür zuständig. Wenn aus der DLL heraus auf COM zugegriffen wird und die aufrufende Anwendung noch kein Apartment eingerichtet hat, muss die DLL dies nachholen

    Comment


    • #3
      Hallo,<br>
      vielen Dank für die sehr schnelle Antwort. Leider funktioniert die DLL auch jetzt nicht.<br> In der zu öffnenden Form befinden sich 2 ADO-Komponenten. Ich habe erst jetzt herausgefunden,daß die DLL <br> funktioniert (soweit erstmal), wenn ich diese herausnehme. Muß ich bei ADO-Komponenten und DLL <br> etwas besonderes beachten?<p>
      Mit freundlichen Grüßen<br> Fran

      Comment


      • #4
        Hallo,

        ja - die DLL muss immer dann über den Aufruf von <b>CoInitialize</b> ein STA-Apartment (ADO liebt STAs) anmelden, wenn der Client dies noch nicht erledigt hat. Das folgende Beispiel stammt aus einer DLL, die für Nicht-Delphi-Anwendungen eine Funktion für das Erzeugen von ACCESS-Datenbanken und den Datenexport in die MDB anbietet, wobei ADOX und ADO verwendet werden. Bevor das Datenmodul mit den ADO Express-Komponenten erzeugt wird, ruft die DLL CoInitialize auf:
        <pre>
        function E_DBInit(const pNewMDBPath: PChar): Integer;
        var
        aCatalog : _Catalog;
        sDS : String;
        sMsg : String;
        begin
        Result := 1;
        bDoCoUninitialize := False;
        bDoDestroyDM_ADO := False;
        try
        //
        sMsg := 'CoInitialize-Fehler';
        CoInitialize(nil);
        bDoCoUninitialize := True;
        //
        sMsg := 'ACCESS-Datenbankdatei konnte nicht gelöscht werden.';
        sMDBPath := pNewMDBPath;
        if FileExists(sMDBPath) then
        DeleteFile(sMDBPath);
        //
        sMsg := 'Fehler beim Zugriff auf die ADOX-Objekte.';
        aCatalog := CoCatalog.Create;
        sConnectionStr := Format('%s%s',[cCONNECTSTRING, sMDBPath]);
        sDS := aCatalog.Create(sConnectionStr);
        aCatalog := nil;
        //
        sMsg := 'Fehler beim Erzeugen des Datenmoduls';
        DM_ADO := TDM_ADO.Create(nil);
        bDoDestroyDM_ADO := True;
        sMsg := 'Fehler beim Erzeugen der Tabelle »Adressen«';
        DM_ADO.DoCreateTable;
        except
        ShowExceptionMsg(sMsg);
        Result := 0;
        end;
        end;
        </pre>
        Über eine zweite exportierte Funktion wird am Ende wieder aufgeräumt:
        <pre>
        function E_DBDone: Integer;
        begin
        Result := 1;
        try
        if bDoDestroyDM_ADO then
        DM_ADO.Free;
        if bDoCoUninitialize then
        CoUninitialize;
        except
        ShowExceptionMsg('E_DBDone-Fehler');
        Result := 0;
        end;
        end;
        </pre&gt

        Comment


        • #5
          Vielen Dankfür die wieder sehr schneller Antwort,<br>
          mit CoInitialize und CoUninitialize funktioniert es.<p> MfG Fran

          Comment

          Working...
          X