DLL 2x laden Problem
-
Hallo,
ich habe ein Problem beim Laden der DLLs, wenn ich von dieser eine Kopie mache, d.h. ich habe eine DLL (DLL1.dll) im Verzeichnis "Plugins". Da mache ich eine Dateikopie von dieser und benenne sie nach DLL2.dll. Es ist also die gleiche DLL, bloß 2x im Verzeichnis "Plugins"!
Nun benutze ich LoadLibrary um die DLL zu laden sowie die dazugehörigen Funktionen. Mein Problem ist, dass es nur funktioniert, wenn wenn 1 DLL zu laden ist. Wenn es 2 sind, besonders die identische Datei, dann gibt es Zugriffsverletzungen. Wie kommt das? Mache ich da was falsch?
DLL-Exports (ich habe nicht alle Funktionen hier aufgeführt
extern "C" { __declspec(dllexport) void __stdcall InitPlugin(DWORD MDBHandle) { //---Form2 wird in DLLMain initialisiert Form2->MDBHandle=(HANDLE)MDBHandle; } //------------------------------------------------------------------------ __declspec(dllexport) void __stdcall ExitPlugin() { //Form2->OnExit(); } //------------------------------------------------------------------------ __declspec(dllexport) DWORD __stdcall GetPluginVersion() { return (MAKELONG(3,0)); // Version 0.3 !!! } }
Laden der Dlls im Hauptprogramm
void __fastcall TForm1::LoadPlugins() { TSearchRec s; PLGInfo *t = new PLGInfo; //------Structure, enthält Infos über DLL ZeroMemory(t,sizeof(PLGInfo)); DWORD version; //---PLGs ist ein Structure, welches die Funktionen aller DLLs enthält PLGs->MDBPlgCount=0; String plgPath=ExtractFilePath(Application->ExeName)+"PlugIns\\"; if (FindFirst(String(plgPath+"*.mdbmod").c_str(),faAnyFile,s)==0) { do //--------PlugIn-Ordner nach PlugIns durchsuchen { if ((s.Attr & faDirectory)!=faDirectory) { //-----Überprüfen ob DLL ein Plugin ist HMODULE dll=LoadLibraryW((plgPath+s.Name).w_str()); if (dll==NULL) continue; if (GetProcAddress(dll,"InitPlugin")==NULL) { FreeLibrary(dll); continue; } //---------Funktionen laden aus DLL und an PlugIn-Struktur übergeben INITPLUGIN InitPlugin =(INITPLUGIN)GetProcAddress(dll,"InitPlugin"); GETPLUGININFO GetPluginInfo =(GETPLUGININFO)GetProcAddress(dll,"GetPluginInfo"); EXECPLUGIN ExecPlugin=(EXECPLUGIN)GetProcAddress(dll,"ExecPlugin"); EXITPLUGIN ExitPlugin=(EXITPLUGIN)GetProcAddress(dll,"ExitPlugin"); GETPLUGINVERSION GetPluginVersion=(GETPLUGINVERSION)GetProcAddress(dll,"GetPluginVersion"); ONNOTIFY OnNotify=(ONNOTIFY)GetProcAddress(dll,"OnNotify"); //------Plugin initialisieren try { ZeroMemory(&PLGs->MDBPlg[PLGs->MDBPlgCount].plgInfo,sizeof(PLGInfo)); PLGs->MDBPlg[PLGs->MDBPlgCount].PlgLoaded=false; InitPlugin((DWORD)Form1->Handle); PLGs->MDBPlg[PLGs->MDBPlgCount].plgDllHandle=dll; PLGs->MDBPlg[PLGs->MDBPlgCount].plgExec=ExecPlugin; PLGs->MDBPlg[PLGs->MDBPlgCount].plgExit=ExitPlugin; PLGs->MDBPlg[PLGs->MDBPlgCount].plgNotify=OnNotify; PLGs->MDBPlg[PLGs->MDBPlgCount].plgVersion=GetPluginVersion(); GetPluginInfo(&PLGs->MDBPlg[PLGs->MDBPlgCount].plgInfo); //-------Menü-Eintrag erstellen TMenuItem *mt; mt= new TMenuItem(Plugins1); mt->OnClick=ExecPluginProc; Plugins1->Add(mt); mt=NULL; PLGs->MDBPlg[PLGs->MDBPlgCount].PlgLoaded=true; PLGs->MDBPlgCount++; } catch(...) { PLGs->MDBPlgCount++; Application->MessageBoxA(String("Beim Laden des PlugIns '"+s.Name+"' ist ein Fehler aufgetreten!").w_str(),L"Fehler",MB_ICONWARNING); } } } while (FindNext(s) == 0); if (PLGs->MDBPlgCount>0) Plugins1->Visible=true; //---MenuItem sichtbar machen, wenn DLLs verfügbar sind. } FindClose(s); }
Mit dem Try-Block, wird die Fehlermeldung, dass die DLL nicht geladen wurde angezeigt, sonst ohne wird wird eine Zugriffsverletzung angezeigt.
Jemand einen Rat?
-
Nur mal ne ganz grundsätzliche Frage: Warum sollte jemand überhaupt so etwas tun wollen!?
-
Es ist ein Test, da ich ein Plugin-Interface für mein Programm mache. Da ich nicht weitere DLLs entwickeln will zum testen, habe ich mir gedacht, nimm die eine DLL 2x...
-
Und wo genau (Zeile?) tritt die Zugriffsverletzung auf?
-
Das sagt er mir nicht in welche Zeile. Aber wenn ich Zeile 39 im Hauptprogramm auskommentiere, dann kommt keine Meldung. Aber das müsste doch egal sein, weil wenn die DLL alleine ist, dann ist alles OK. Mit der Kopie gibt es Probleme!
Warum? Da ist doch nix...
-
Was für einen komischen Debugger verwendest du da der dir sowas nicht sagt?
-
Also ich verwende den eingebauten von der IDE. Aber er springt in eine *.pas Datei und da ist Assemblercode. Jedenfalls verstehe ich da ganze nicht. Oder darf man nicht die DLL kopieren und dann nochmal laden?
-
Mir fällt spontan kein Grund ein warum sowas grundsätzlich unmöglich sein sollte (auch wenns jenseits von sinnvoll ist), darum wärs eben mal gut zu wissen was genau der Fehler ist...
-
Ich versuche mal ein neues Hauptprogramm zu erstellen, vielleicht übersehe ich was...
-
Warum nicht einfach versuchen herauszufinden was der Fehler ist!?
-
Also, der Quelltext des Hauptprogrammes beträgt in der Haupt-Unit 150 KB, es ist also ein großes Projekt. In dem neuen kleineren Hauptprogramm, sagt mir der Debugger, dass die Werte von der Funktion in die Structure von PLG
GetPluginInfo(&PLGs->MDBPlg[PLGs->MDBPlgCount].plgInfo);
immer Null sind, also leer. Nun, vermutlich liegt der Fehler in der DLL und nicht im Hauptprogramm