DLL-Resource statisch einbinden
-
Hallo,
ich bräuchte mal Eure Hilfe.Ich lade ein Icon aus einer DLL dynamisch. Das Icon wird als Bild angezeigt:
__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){ TIcon *icon = new Graphics::TIcon; HINSTANCE hinstDLL=LoadLibrary("dynamischeDLL.dll"); if (hinstDLL != 0){ Form1->Caption = "DLL wurde geladen"; icon->Handle=LoadImage(hinstDLL,"ICON_0", IMAGE_ICON, 64,64, LR_DEFAULTSIZE); Image1->Canvas->Draw(1,1,icon); //Image1 im OI erstellt } FreeLibrary(hinstDLL); delete icon; }Aber, wie geht das mit einer statischen Einbindung?

Eine LIB-Datei habe ich von meiner DLL mit IMPLIB.EXE auf DOS-Ebene erstellt und in das Projekt eingefügt.
Ich habe 'mal eine Version als statisch gebastelt, siehe unten. Leider wird damit kein Bild angezeigt. Ich glaube der Fehler liegt in HINSTANCE. Ich weiß nicht, was ich dieser Variablen zuweisen soll? Kann jemand helfen?__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){ TIcon *icon = new Graphics::TIcon; HINSTANCE hinstDLL; //das ist sicher falsch, ich weiß nicht, was ich hier hinstDLL zuweisen soll!! if (hinstDLL != 0){ Form1->Caption = "DLL wurde geladen"; icon->Handle=LoadImage(hinstDLL,"ICON_0", IMAGE_ICON, 64,64, LR_DEFAULTSIZE); Image1->Canvas->Draw(1,1,icon); //Image1 im OI erstellt } delete icon; }
-
thunderbol4 schrieb:
Leider wird damit kein Bild angezeigt. Ich glaube der Fehler liegt in HINSTANCE. Ich weiß nicht, was ich dieser Variablen zuweisen soll?
GetModuleHandle ("statischeDLL.dll")
-
Hallo @audacia:
habe das 'mal für die statische Variante probiert:
__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){ TIcon *icon = new Graphics::TIcon; HMODULE hmoduleDLL=GetModuleHandle("statischeDLL.dll"); if (hmoduleDLL != 0){ Form1->Caption = "DLL wurde geladen."; icon->Handle=LoadImage(hmoduleDLL,"ICON_0", IMAGE_ICON, 64, 64, LR_DEFAULTSIZE); Image1->Canvas->Draw(1,1,icon); }; delete icon; }Leider noch kein Erfolg. Der Debugger zeigt mir für hmoduleDLL den Wert NULL an.
Mit dem Hexeditor habe ich mir die LIB-Datei näher angeschaut (Hatte ich mit implib.exe aus der DLL erzeugt).
1. Die Größe der LIB-Datei ist nur 1 kB. Im Vergleich dazu hat die DLL-Datei 82 kB.
2. Die LIB-Datei besteht fast nur aus OOh, 3 oder 4 Bytes haben einen zählbaren Wert.Ist das normal?

Wenn der Code oben okay ist, kann's eigentlich nur daran liegen oder?
-
thunderbol4 schrieb:
Wenn der Code oben okay ist, kann's eigentlich nur daran liegen oder?
Vermutlich ja. Ob die .LIB-Datei korrekt ist, kannst du mit TDUMP herausfinden. Wenn sie fehlerhaft ist, solltest du evtl. mal ein wenig mit den Optionen von IMPLIB herumprobieren (oder, wenn du C++Builder 2007 hast, IMPLIB32 verwenden).
Falls du die DLL selbst kompilierst, erstellt dir der Linker übrigens gleich die passende .LIB-Datei.
-
Hallo @audacia:
bin leider immer noch auf Fehlersuche.HMODULE hmoduleDLL=GetModuleHandle("statischeDLL.dll");ergibt immer noch NULL.

Bin auf Deinen Vorschlag eingegangen und habe mit meinem Builder6 mit DLL-Experten ein DLL-Projekt erstellt Dort habe ich eine Icon-Resource als RC-Datei eingebunden. Nach der Compilierung und dem Linken hatte ich eine LIB- und DLL-Datei erhalten. Die LIB-Datei schien diesmal in Ordnung (?
?). Sie war immerhin auf 10kB angewachsen (vorher 1kB).
Mit meinem PEResourceExplorer (Programm zur Bearbeitung von Resourcen) konnte ich an der fertigen DLL keine Fehler entdecken. Die Icons waren so eingebaut, wie in der RC-Datei festgelegt.Stehe vor einem Rätsel.
Woran kann man erkennen, dass die LIB-Datei okay ist?
Andererseits kann ich auch nicht verstehen, weshalb ich bei GetModuleHandle immer noch NULL erhalte. Woran kann das denn liegen? Mit LoadLibrary klappt das doch auch?!Vielleicht hast Du ja noch eine Idee, trotzdem schon 'mal Dank für Deine Bemühungen.
-
Hallo thunderbol4,
wenn
GetModuleHandle("statischeDLL.dll")NULL zurückgibt schau dir mal den Fehler mit
DWORD GetLastError(VOID)an.
Gruß
Peter
-
Hallo @Peter24:
Habe das 'mal probiert:
HMODULE hmoduleDLL=GetModuleHandle("statischeDLL.dll"); if (hmoduleDLL != 0){ ... } else{ int fehler = GetLastError(); Form1->Caption = "DLL nicht gefunden " + IntToStr(fehler); }Der Fehler hat die Nummer: 126
Im Google deutet alles daraufhin, dass er das DLL-Modul nicht findet.(oder vielleicht LIB- ??).
Versteh ich nicht! Alle Dateien befinden sich im Projektverzeichnis. Habe die Verzeichnisoptionen und Dateinamen geprüft. Die sind auch okay.Habe mit einem Tool die DLL ein bißchen näher untersucht, kann aber nicht sagen, ob die so okay ist:
*Turbo Dump Version 5.0.16.12 Copyright (c) 1988, 2000 Inprise Corporation
Display of File D:\..\DLL STATISCH\STATISCHEDLL.DLLIMPORT: rtl60.bpl
IMPORT: rtl60.bpl
IMPORT: rtl60.bpl
IMPORT: rtl60.bpl
IMPORT: rtl60.bpl
IMPORT: rtl60.bpl
IMPORT: rtl60.bpl
IMPORT: rtl60.bpl
IMPORT: BORLNDMM.DLL
IMPORT: KERNEL32.DLL
IMPORT: CC3260MT.DLL*und für die LIB-Datei zeigt mir das Tool nur Folgendes an:
*Publics by module
statischeDLL size = 0
___CPPdebugHook*Vielleicht gibt's noch einen Hinweis?
-
Wenn du eine statische Bibliothek in deinem Programm eingebunden hast, dann kannst du natürlich nicht nach einer DLL ("Dynamic Link Library") suchen lassen.
Der Funktion 'LoadImage' mußt du dann einfach das Instanz-Handle deiner Applikation zuweisen (s. WinMain) bzw. probiere einfach mal NULL aus.
-
Th schrieb:
Wenn du eine statische Bibliothek in deinem Programm eingebunden hast, dann kannst du natürlich nicht nach einer DLL ("Dynamic Link Library") suchen lassen.
Soweit ich das verstanden habe, hat er eine DLL statisch eingebunden.
Das Anwengungs-Modul ist erhältlich über GetModuleHandle (NULL).
Btw, der Fehlercode 126 lautet im Klartext "The specified module could not be found". Wie genau gehst du denn vor beim Einbinden der DLL?
-
Eine DLL kann man NICHT statisch einbinden, sondern nur eine Bibliothek (Lib).
Daher kann mittels GetModuleHandle() ja auch kein Modul 'xxx.dll' im laufenden Prozess gefunden werden.
-
Th schrieb:
Eine DLL kann man NICHT statisch einbinden
Ist dir dann der Begriff "statisch linken" genehm?

Schau dir doch einfach die Beschreibung seines Vorgehens an, da wird das deutlich.
thunderbol4 schrieb:
Bin auf Deinen Vorschlag eingegangen und habe mit meinem Builder6 mit DLL-Experten ein DLL-Projekt erstellt Dort habe ich eine Icon-Resource als RC-Datei eingebunden. Nach der Compilierung und dem Linken hatte ich eine LIB- und DLL-Datei erhalten. Die LIB-Datei schien diesmal in Ordnung (?
?). Sie war immerhin auf 10kB angewachsen (vorher 1kB).
-
Grundlage für mein Vorgehen war das hier:
http://www.marquardtnet.info/cecke/tutorials.8/8_dll.html*Die statische DLL nutzen:
Im C++Builder "Projekt -> Dem Projekt hinzufügen" auswählen
Die zu der DLL gehörende *.lib Datei hinzufügen
In dem Modul, welches die DLL-Funktionen oder Klassen benutzt die zur DLL gehörende .h Datei einbinden
(
habe keine *.h bei der Erzeugung der DLL bekommen, da es sich hier um eine reine Resourcendatei handelt
)
Alle Funkionen der DLL stehen zur Verfügung
Die DLL muß entweder im Verzeichnis der Applikation, im Windows/System/-Verzeichnis oder in einem Verzeichnis liegen,
welches in der Umgebungsvariablen PATH enthalten ist.
FertigGenauso habe ich es dann gemacht:
Die Projektdatei zur Erzeugung der DLL und LIB
ProjectGroup1
|
statischeDLL.dll
|_ statischeDLL.res
|_ statischeDLL.bpf
|_ Unit1.cpp
|_ MeineIcons.rcDie Projektdatei für die EXE (soll Icons laden und dazu die DLL nutzen...)
ProjectGroup1
|
Project1.exe
|_Project1.res
|_Project1.cpp
|_Unit1.cpp
|_statischeDLL.libGibt's noch einen Anstoß? So schnell möchte ich eigentlich nicht aufgeben

-
Hallo thunderbol4,
Wie es aussieht hast Du die DLL richtig eingebunden.
Ich vermute mal das die DLL nicht geladen wird da sie keine Funktionen exportiert.
Pack doch mal ein Funktion in die DLL die z.B. eine MessageBox mit dem Text "Hallo DLL" bringt.
Wenn Du die Funktion im Programm aufrufen kannst dann weisst Du das die DLL geladen wurde und dann kannst Du mit Sicherheit auch auf die Resourcen zugreifen.Gruß Peter
-
Hallo @Peter24:
daran hatte ich auch schon gedacht. Werde mal eine dummy-Funktion einbauen und melde mich zum Ergebnis was passiert istBis dann
-
Vielen Dank @Peter24, @audacia u @Th
wie von @Peter24 vorgeschlagen
, habe ich die kleine Anwendung mit einer dummy-Funktion in der DLL-Datei durchgespielt.
Siehe da, meine Icon's werden jetzt angezeigt
. Auch mit der statischen DLL!
Die dummy-Funktion muss allerdings im EXE-Projekt aufgerufen werden. Sie nur zu deklarieren reicht scheinbar nicht.//DLL-Projekt, i d d Icon-Resource eingebunden wird #include <vcl.h> #include <windows.h> #pragma hdrstop // Funktion für Export deklarieren extern "C" __declspec(dllexport) int dummy(int); #pragma argsused int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { return 1; } // dummy Funktion int dummy(int i){return i+i}//EXE-Projekt #include <vcl.h> #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; // Funktion aus der DLL importieren extern "C" __declspec(dllimport) int dummy(int); __fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){ TIcon *icon = new Graphics::TIcon; HMODULE hmoduleDLL=GetModuleHandle("statischeDLL.dll"); if (hmoduleDLL != 0){ Form1->Caption = "DLL wurde geladen."; icon->Handle=LoadImage(hmoduleDLL,"ICON_1", IMAGE_ICON, 32,32, LR_DEFAULTSIZE); ImageList1->AddIcon(icon); Image1->Canvas->Draw(1,1,icon); } else{ int fehler = GetLastError(); Form1->Caption = "DLL nicht gefunden "+ IntToStr(fehler); } delete icon; int j=dummy(0); }