![]() |
DLL wird nicht geladen - Warum nicht???
Hallo!
Vor einiger Zeit habe ich hier eine Frage zu Interfaces gepostet. Als Antwort erhielt ich u.a. folgenden Link: ![]() Im folgenden Code wird die DLL, die ein Plugin enthält, das mit Interfaces arbeitet, nicht geladen. Kennt jemand den Grund dafür?
Delphi-Quellcode:
Oder ist es die Prozedur, die er nicht findet? Wenn ich die Unit ShareMem als ertes in meiner Formular Unit aufführe, erhalte ich ein Meldungsfenster mit dem Titel "Fehler beim Starten des Programms" und der Meldung "Die Datei Delphimm.dll ist verknüpft mit dem fehlenden Export-BORLNDMM.DLL-DunpBlocks". Was hat das zu bedeuten? Der Code für die Dll ist exakt der gleiche, wie in dem Thread, der oben als Link angegeben ist.
procedure TForm1.mCfgToolsClick(Sender: TObject);
type TProcInitPlg = function: IPlugin; stdcall; var fName: string; iPlg: IPlugin; aProc: TProcInitPlg; hDLL: HWND; fProc: TFarProc; mApp: TApp; begin ShowMessage(GetCurrentDir); //hab die .dll extra dahin kopiert! with TOpenDialog.Create(nil) do begin if Execute then fName := FileName else begin ShowMessage('Datei existiert nicht!'); Exit; end; end; (* fName := GetCurrentDir; if fName[Length(fName)]<>'\' then fName := fName + '\'; fName := fName + 'plugin.dll'; *) hDll := LoadLibrary(@fName[1]); fProc := GetProcAddress(hDLL,'InitPlugin'); if fProc <> nil then begin @aProc := fProc; end else begin ShowMessage('DLL konnte nicht geladen werden!'); Exit; end; iPlg := aProc; showMessage(iPlg.GetName); iPlg := nil; FreeLibrary(hDLL); end; Schon mal Danke im Voraus für Eure Hilfe sagt Delphifan2004 |
Re: DLL wird nicht geladen - Warum nicht???
Zitat:
Delphi-Quellcode:
program Project1;
uses ShareMem, Forms, Unit1 in 'Unit1.pas' {Form1}; {$R *.res} begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end.
Delphi-Quellcode:
library Project2;
uses ShareMem, SysUtils, Classes; {$R *.res} begin end. |
Re: DLL wird nicht geladen - Warum nicht???
Zitat:
Zitat:
Schreib den Code mal so um:
Delphi-Quellcode:
und teile mit, ob, und wenn ja was für ein Fehlercode kommt.
SetLastError(0);
hDll := LoadLibrary(@fName[1]); if hDll = 0 then ShowMessage(IntToStr(GetLastError)); |
Re: DLL wird nicht geladen - Warum nicht???
Hallo tommie-lie!
Habe mit GetLastError den Fehlercode abgefragt, wie Du vorgeschlagen hast. Ich erhalte Fehlercode 31. Da ich keinen Fehlertext dazu habe (In meiner D3 Pro Hilfe steht nix dazu) kann ich damit momentan nix anfangen! Wo gibt es Erläuterungen zu den Fehlercodes? Gruß Delphifan2004 |
Re: DLL wird nicht geladen - Warum nicht???
Probiers mal damit:
Delphi-Quellcode:
ShowMessage(SysErrorMessage(GetLastError));
|
Re: DLL wird nicht geladen - Warum nicht???
Hallo Bernhard ...!
Danke erst mal für den Tipp mit SysErrorMessage(). Damit erhalte ich die Meldung: "Ein an das System angeschlossenes Gerät funktioniert nicht" Frage ist: Welches? Ich tippe auf ein Problem mit der Stringübergabe, weil: wenn ich die Unit ShareMem in der Projektdatei und/oder in der Form-Unit einbinde, erhalte ich das Meldungsfenster mit dem Titel "Fehler beim Starten des Programms" und der Meldung "Die Datei Delphimm.dll ist verknüpft mit dem fehlenden Export-BORLNDMM.DLL-DunpBlocks". Was hat das zu bedeuten? Außerdem erscheint ein Meldungsfenster mit dem Namen meiner Anwendung als Titel und der Meldung "Vorgang kann nicht erzeugt werden" Um auf obigen Text für SysErrorMessage(GetLastError) zurückzukommen, welches Gerät soll denn sonst für das Funktionieren meiner Anwendung so entscheidend sein. Da ich mit ShareMem Probleme habe, tippe ich darauf, das das die Ursache ist. Bloß, warum lädt er dann meine Dll nicht? Eher müßte ich doch wegen fehlender ShareMem ne Exception kriegen, wenn ich Strings übergeben will, wozu ja ShareMem gebraucht wird. Irgendwas stimmt hier nicht. Bloß Was!?!? verzweifelte Grüße Delphifan2004 |
Re: DLL wird nicht geladen - Warum nicht???
Pfff, solche Fehlercodes kennt man auswendig! :mrgreen: Die Fehlercodes sind in einem aktuellen PSDK enthalten, oder alternativ online im MSDN.
31 ist ERROR_GEN_FAILURE und heißt laut PSDK, daß eine Device nicht funktioniert. Ich hatte eigentlich eher auf 2 (file not found) oder 32 (sharing violation) gehofft. Mit 31 kann ich nicht viel anfangen, du könntest es mal mit einer anderen DLL probieren, die nichts mit Interfaces und sonstigem zu tun hat, einfach nur eine exportierte Funktion die zum Beispiel 'ne Messagebox anzeigt. Nachtrag (ja, diesmal funktionierte der rote Kasten mal!): "Gerät" heißt nicht ein Ding, das du anfassen kannst und irgendwo einstöpselst, es kann auch eine Datei sein. Und was machst du überhaupt mit der ShareMem? Willst du Pascal-Strings oder -Objekte an Funktionen der DLL übergeben? Ich dachte um das zu vermeiden willst du Interfaces verwenden? |
Re: DLL wird nicht geladen - Warum nicht???
Delphi-Quellcode:
Aha. Und wer sagt dir, dass das aktuelle Verzeichnis auch das ist, wo du deine DLL hinkopiert hast?
ShowMessage(GetCurrentDir); //hab die .dll extra dahin kopiert!
|
Re: DLL wird nicht geladen - Warum nicht???
Zitat:
|
Re: DLL wird nicht geladen - Warum nicht???
Hm, OK.
|
Re: DLL wird nicht geladen - Warum nicht???
Hab das mal mit Delphi 3 unter Windows 95 getestet. Die Fehlermeldung kommt bei mir auch. Aber nur dann, wenn es sich nicht um eine DLL handelt.
Also hat delphifan2004 wohl keine DLL im TOpenDialog ausgewählt. |
Re: DLL wird nicht geladen - Warum nicht???
Hallo tommie-lie!
Hab jetzt die folgende Dll erstellt, deren Aufruf funktioniert, aber mit paar kleinen Schönheitsfehlern. Zuerst der Code der DLL:
Delphi-Quellcode:
Mit dieser Dll klappt das Laden und die Prozedur MsgBox läßt sich aufrufen. Bloß, mit der Zeile iPlg := aProc will ich doch erst mal einen Prozedurzeiger zuweisen. Erfolgt da ein Aufruf immer explizit, oder habe ich wieder mal ein Verständnisproblem?
library MsgBoxDll;
uses SysUtils, Dialogs, Classes; procedure MsgBox; stdcall; begin ShowMessage('Diese Box ist in einer DLL codiert!'); end; exports MsgBox; begin end. //Habe mal ne andere Dll erzeugt, die ich jetzt lade. //Habe den Code der Unit IntfApp jetzt wie folt geändert: //Hier, wie gehabt, der OpenDialog SetLastError(0); hDll := LoadLibrary(@fName[1]); if hDll = 0 then //kommt jetzt nicht mehr, Dll wird also geladen ShowMessage(SysErrorMessage(GetLastError)); fProc := GetProcAddress(hDLL,'MsgBox'); //Prozedur MsgBox aus meiner DLL zuweisen //da ich jetzt die obige Dll mit dieser Prozedur lade if fProc <> nil then begin @aProc := fProc; end else begin ShowMessage('DLL konnte nicht geladen werden!'); Exit; end; iPlg := aProc; //Hier erscheint dann die MessageBox (Procedure wird also aufgerufen) showMessage(iPlg.GetName); //Hier EAccessViolation ===WARUM???=== iPlg := nil; FreeLibrary(hDLL); end; Wenn ich die MessageBox aus der Dll mit [Ok] quittiere, erhalte ich anschließend eine EAccessViolation. Warum das nun wieder? Zitat:
Du sagst, Gerät kann auch eine Datei sein. Im konkreten Fall vermutlich unsere Dll. Zitat:
Zitat:
Delphifan2004 |
Re: DLL wird nicht geladen - Warum nicht???
Zitat:
|
Re: DLL wird nicht geladen - Warum nicht???
Hallo Delphifan!
Haste auch den Prozedurtyp der neuen Situation angepasst? Wenn nicht, wundert mich die EAccessviolation nicht. Guck mal nach! Kannste glauben. |
Re: DLL wird nicht geladen - Warum nicht???
Zitat:
aProc ist die Funktion selbst, denn sie sit vom Typ TProcInitPlg. Wenn du in einem Delphi-Programm den Namen einer Funktion schreibst, die keinen Parameter benötigt, wird die Methode aufgerufen. Zum Beispiel GetLastError, schreibst du ja auch nicht, wie es eigentlich sinnvoll wäre, GetLastError(). Wenn du also iPlg := aProc hast, wird aProc aufgerufen und der Rückgabewert der Funktion der Variable iPlg zugewiesen. So, wie du deine Variablen deklariert hast, macht das für mich auch Sinn, daß iPlg := aProc die Funktion aProc auch aufruft, erscheint mir also richtig so (nicht nur syntaktisch, sondern auch semantisch). Zitat:
Zitat:
Hast du denn mal vor dem Laden fName überprüft, zum Beispiel indem du es in einer MessageBox anzeigst? Zitat:
|
Re: DLL wird nicht geladen - Warum nicht???
Hallo tommie-lie!
Danke erst mal für Deine Antwort. Zitat:
Damit weise ich an iPlg das Interface zu, das mit InitPlugin initialisiert wird. Damit ist erklärt, warum an dieser Stelle die Routine aufgerufen wird und die Zugriffsverletzung tritt auf, weil ich in meiner eigenen Test-Dll die exportierte Routine MsgBox als Prozedur definiert habe. Soweit Klar. Rest wird am Wochenende auseinander genommen. Zitat:
@tommie-lie: Ob das "noch inkompatibler" wird, weiß ich nicht. Wenn die Unit OpenSource ist, muss ich sie halt bei Verwendung mit weitergeben. Hier geht es aber ohnehin erst mal darum, das Beispiel zu verstehen und da ist halt ein AnsiString als Funktionsrückgabe dabei. In der praktischen Anwendung kann ich dann bei Stringübergaben immer noch PChars nehmen. Es grüßt Delphifan2004 |
Re: DLL wird nicht geladen - Warum nicht???
Zitat:
Zitat:
Zitat:
Zitat:
|
Re: DLL wird nicht geladen - Warum nicht???
Zitat:
Was nun delphifan2004 macht, ist mir eigentlich völlig egal. Und auch nichts mit dem Thema zu tun. |
Re: DLL wird nicht geladen - Warum nicht???
Hallo!
Jetzt das Ganze noch mal im richtigen Thread: Ich beziehe mich immer noch aud diesen Link: ![]() und diesen Link hier: ![]() Der folgende Codeausschnitt soll mein Plugin ausführen:
Delphi-Quellcode:
Die MessageBox für den Fehlerfall erscheint nicht, und trotzdem erscheint der erwartete Text nach Drücken von Strg+V nicht in meinem Editor?
mApp := TApp.Create;
if Assigned(iPlg) then begin iPlg.Execute(mApp); end else ShowMessage('Plugin konnte nicht initialisiert werden!'); Was ist jetzt noch falsch? Die Dll wird jetzt geladen und ich bekomme auch den Text "Mein Testplugin" angezeigt. Aber der Text: "Dieser Text erscheint im Editor" erscheint nicht. Warum nicht? Zur Erinnerung noch mal die Execute Methode:
Delphi-Quellcode:
Sorry, Ich brauche doch noch mal Hilfe!
function TPlugin.Execute(App: IApp): Integer;
begin Result := 1; // True App.GetEditor.Content := 'Dieser Text erscheint im Editor.'; App.GetEditor.CopyToClipboard; end; Es grüßt Delphifan2004 |
Re: DLL wird nicht geladen - Warum nicht???
Zitat:
Zitat:
|
Re: DLL wird nicht geladen - Warum nicht???
Zitat:
Delphi-Quellcode:
Sie steht vor der Zuweisung der Editorsachen.
ShowMessage('Execute-Methode wird aufgerufen!');
Ergebnis: Der Aufruf der Methode funzt. Ich kriege die Meldung zu sehen. Zitat:
Daher kann ich bisher nur vom Quelltext ausgehen. Der entspricht dem aus dem Thread mit dem Plugin-Beispiel ohne eigene Anpassungen. (nur kopiert). Da werd ich mal versuchen, ob mit Debugging was zu sehen ist. Bis bald Delphifan2004 |
Re: DLL wird nicht geladen - Warum nicht???
Hallo!
Zitat:
Delphi-Quellcode:
Die nächste Frage gehört zwar streng genommen in einen eigenen Thread, aber da sie inhaltlich zu meinem aktuellen Problem gehört (Dll für Plugin mittels Interface), stelle ich sie dennoch gleich hier, in der Hoffnung, das es darauf eine einfache Antwort gibt. (geeigneter externer Debugger o.ä.)
type
TApp = class(TInterfacedObject, IApp) private FEditor: IEditor; public constructor Create; ... //Rest zum Verständnis hier nicht relevant end; constructor TApp.Create; begin inherited Create; FEditor := TEditorAdapter.Create(Form1.SynEdit); //SynEdit ist nun der konkrete Editor //der wird aber an das Interface zugewiesen end; Zitat:
Da ich das vorliegende Problem ja, hoffe ich zumindest, irgendwann gelöst haben werde, ergeben sich für mich folgende Überlegungen: ActiveX bzw. COM ist doch sicher ein Standard. So müßte es doch vordefinierte Interfaces für alle nur möglichen Anwendungsfälle geben. Allerdings sind diese, wie ich bei "Typbibliothek importieren" sehe, ungleich komplexer. Ein eigenes kleineres Interface für die konkrete Anwendung ist da sicher für den Anfang besser. Wenn ich aber eine Standard-Schnittstelle bereitstellen will? Delphi läßt sich ja beispielsweise auch durch Plugins erweitern. Wo finde ich da eine Spezifikation? (nicht für Delphi Schnittstelle, dafür gibt es die Doku, sondern für den allgemeinen Standard) Da der Aufwand hier für das im Thread behandelte Problem schon beachtlich ist, will ich, wenn ich mich schon damit beschäftige, gleich was richtiges machen, sprich, ein standardisiertes Interface haben. Es geht konkret um einen Editor, der durch Plugins erweiterbar sein soll. Wenn ich den später als OpenSource verfügbar mache und jemand hat einen Erweiterungswunsch, will ich einfach ein zusätzliches Plugin schreiben können, das den Wunsch erfüllt. Es grüßt Delphifan2004 |
Re: DLL wird nicht geladen - Warum nicht???
Hallo!
Zitat:
abhängig davon würde ich an Deiner Stelle trotzdem erst noch bissl mit dem Beispielprogramm hier rumspielen. Das hilft später, die komplexeren Dinge besser zu verstehen. Viel Erfolg wünscht schöni |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:20 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz