DllMain in Programm einbinden ohne weitere Bibliotheks-Funktion
-
Hallo,
ich suche jetzt schon eine Zeitlang nach einer Lösung, wie man die DllMain von einer DLL-Bibliotheksdatei in eine ausführbare Programmdatei "gelinkt" bekommt. Dabei soll jedoch keine Funktion aus der DLL-Datei von der ausführbaren Datei aufgerufen werden (denn das würde funktionieren).
Beispiel:
DllMain.h:
#ifndef DLLMAIN_H #define DLLMAIN_H #include <Windows.h> #ifdef DLL_EXPORT #define DLL_API __declspec(dllexport) #else #define DLL_API __declspec(dllimport) #endif BOOL DLL_API WINAPI DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved); #endif // DLLMAIN_H
DllMain.cpp
#define DLL_EXPORT #include "DllMain.h" BOOL WINAPI DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { MessageBox(NULL, TEXT("Ich bin die DLL-Datei.\0"), TEXT("DLL-Message\0"), MB_OK); return TRUE; }
main.h:
#ifndef MAIN_H #define MAIN_H #include <windows.h> #include "..\..\Dll\Dll\DllMain.h" #endif // MAIN_H
main.cpp
#include "main.h" int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { MessageBox(NULL, TEXT("Ich bin die EXE-Datei.\0"), TEXT("EXE-Message\0"), MB_OK); return 0; }
Hat jemand einen Lösungsvorschlag für dieses Problem oder kann jemand eventuell hilfreiche Tipps?
PS: Die Entwicklungsumgebung die ich verwende ist VisualStudio 2010.
-
REXPILS schrieb:
Dabei soll jedoch keine Funktion aus der DLL-Datei von der ausführbaren Datei aufgerufen werden (denn das würde funktionieren).
Wie meinst du ?
Was willst du letztlich erreichen und warum ?
DlLMain ist keine normale Funktion, sie wird automatisch aufgerufen wenn die DLL ge-/entladen wird. Warum und wie genau willst du Funktion selber aufrufen ?
-
Ziel ist es mit der DllMain eine Initialisierung durchzuführen z.B. für Windows-Klassen.
DlLMain ist keine normale Funktion, sie wird automatisch aufgerufen wenn die DLL ge-/entladen wird.
Dies ist mir bewusst und genau das ist was ich will. Nur scheint dies nicht möglich zu sein, da die DLL nicht in die Import-Tabelle der EXE-Datei eingetragen wird. Gibt es da eine Möglichkeit dies zu realisieren?
Warum und wie genau willst du Funktion selber aufrufen ?
Die DllMain will ich gar nicht aufrufen, da dies ja, wie schon erwähnt wurde, am Anfang bzw. Ende der EXE-Datei automatisch geschieht. Es soll in der DLL-Datei auch weitere Funktionen geben, welche in Abhängigkeit von der Initialisierung arbeiten, diese Funktionen werden jedoch nicht von der EXE-Datei direkt aufgerufen.
Ich hoffe, mein Problem ist jetzt etwas deutlicher geworden.
-
REXPILS schrieb:
Ich hoffe, mein Problem ist jetzt etwas deutlicher geworden.
Nein.
-
REXPILS schrieb:
DlLMain ist keine normale Funktion, sie wird automatisch aufgerufen wenn die DLL ge-/entladen wird.
Dies ist mir bewusst und genau das ist was ich will. Nur scheint dies nicht möglich zu sein, da die DLL nicht in die Import-Tabelle der EXE-Datei eingetragen wird. Gibt es da eine Möglichkeit dies zu realisieren?
Du meinst dein DllMain wird nicht aufgerufen ? Du weißt schon dass LoadLibraryA DllMain auch aufruft ?
-
Du weißt schon dass LoadLibraryA DllMain auch aufruft ?
Das sollte ich vielleicht noch erwähnen. Die DLL-Datei soll statisch geladen werden, daher ist auch kein LoadLibraryA-Aufruf im Quellcode enthalten.
@Swordfish:
Was ist an meinem Problem unverständlich?
-
DarkShadow44 schrieb:
Was willst du letztlich erreichen und warum ?
Dies. Ich verstehe immer noch nicht, was für ein Problem du denn jetzt lösen möchtest.
Nur so am Rande: Was sollen eigentlich die \0 am Ende der Stringliterale?
-
Das Problem ist die Einbindung der DllMain.
Hauptsächlich geht es mir zur Zeit darum, dass ich ein eigenes Steuerelement (WNDCLASS) erstelle, welches per DLL-Datei eingebunden wird. Wie z.B. Microsoft das Steuerelement "Button" mit der CreateWindow-Funktion erzeugt möchte ich anstatt des Buttons ein eigenes Steuerelement einbinden.Beispiel:
CreateWindow(TEXT("button"), NULL, WS_CHILD | WS_VISIBLE | BS_ICON | BS_FLAT | BS_PUSHBUTTON, 0, 0, 0, 0, hWndParent, NULL, hInstance, NULL);CreateWindow(TEXT("EigeneSteuerelement"), NULL, WS_CHILD | WS_VISIBLE | BS_ICON | BS_FLAT | BS_PUSHBUTTON, 0, 0, 0, 0, hWndParent, NULL, hInstance, NULL);
Das "EigeneSteuerelement" soll in dieser DllMain registriert usw. werden.
Ein anderer Ansatz könnte eventuell auch helfen, jedoch soll er nicht von der Anwendung des oben gezeigten Beispiels abweichen.Nur so am Rande: Was sollen eigentlich die \0 am Ende der Stringliterale?
Das nennt sich Nullterminierung und soll das String-Ende anzeigen.
-
REXPILS schrieb:
Das "EigeneSteuerelement" soll in dieser DllMain registriert usw. werden.
Was heißt "registriert werden" und wozu?
REXPILS schrieb:
Nur so am Rande: Was sollen eigentlich die \0 am Ende der Stringliterale?
Das nennt sich Nullterminierung und soll das String-Ende anzeigen.
Möchtest du nicht vielleicht vor der WinAPI und DLLs DIE SPRACHE AN SICH LERNEN!?
-
REXPILS schrieb:
Das "EigeneSteuerelement" soll in dieser DllMain registriert usw. werden.
Mal davon abgesehen, dass ich im Moment nicht ganz sicher weiß, ob man das überhaupt in
DllMain
machen darf (wahrscheinlich aber schon), schreibe doch lieberRegisterEigeneSteuerelement
und vielleicht auchUnregisterEigeneSteuerelement
. Exportiere sie und rufe sie dann in der EXE auf. So einfach könnte das sein.Warum muss das bei dir so kompliziert sein?
-
Swordfish schrieb:
REXPILS schrieb:
Das "EigeneSteuerelement" soll in dieser DllMain registriert usw. werden.
Was heißt "registriert werden" und wozu?
Meine Güte, wie merkbefreit bist Du denn? Er meint natürlich RegisterClass/Ex. Das funktioniert aber nicht in DllMain, da diese Funktionen aus user32.dll und nicht aus kernel32.dll stammen.
Also eigene Initialisierungs-Funktion bauen, wie EinGast bereits sagte.
-
Mox schrieb:
Swordfish schrieb:
REXPILS schrieb:
Das "EigeneSteuerelement" soll in dieser DllMain registriert usw. werden.
Was heißt "registriert werden" und wozu?
Er meint natürlich RegisterClass/Ex. Das funktioniert aber nicht in DllMain, da diese Funktionen aus user32.dll und nicht aus kernel32.dll stammen.
Es funktioniert nicht zuverlässig.
Das Problem ist nur dass es meistens doch funktioniert. Gerade im Fall von USER32 Funktionen, weil die USER32 meist schon geladen & initialisiert ist wenn die DllMain von eigenen DLLs läuft.EinGast schrieb:
Warum muss das bei dir so kompliziert sein?
Das frag' ich mich auch oft.
-
hustbaer schrieb:
EinGast schrieb:
Warum muss das bei dir so kompliziert sein?
Das frag' ich mich auch oft.
Ich frage mich eher, warum Ihr Euch künstlich doof stellt. Die Motivation liegt doch auf der Hand: Die DLL wird geladen und die Fensterklassen automatisch registriert (@Swordfish: Fensterklassen registrieren heißt RegisterClass/Ex aufrufen). Das kann für den Anwender schön einfach sein, das Gegenteil von kompliziert. Die ursprüngliche Frage halte ich von daher für mehr als berechtigt.
Aber da er ja nun weiß, dass das so nicht zuverlässig funktioniert, wird er das ja jetzt auch anders machen (müssen).
-
Und eben das ist, so wie er sich es vorstellt, nicht möglich. Entweder lädt er die DLL, z.B mit
LoadLibrary
, oder seine EXE muss etwas aus der DLL importieren.Das kann auch, wenn es, aus welchen Grund auch immer,
DllMain
sein muss, ebenDllMain
sein (inmain.cpp
einfügen):static BOOL (WINAPI *dllmain)(HINSTANCE, DWORD, LPVOID) = DllMain;
Na ja.
-
Alternativ (nicht das jemand noch sagt, es ginge auch anders) kann die Linker-Option /INCLUDE verwendet werden:
/INCLUDE:__imp__DllMain@12
Das ist jedoch in meinen Augen nicht so einfach wie eine Funktion, die nichts macht oder seine Kontrollelemente registriert, aufzurufen.
-
DLL in EXE einbinden: http://www.oreans.com/xbundler.php
Man findet auch sicher irgendwo source für sowas..
-
EinGast schrieb:
Und eben das ist, so wie er sich es vorstellt, nicht möglich.
<Loriot>Ach was?</Loriot>
Das haben wir doch nun bereits mehrfach festgestellt.
-
Vielen Dank für die Antworten.
Dann komm ich wohl nicht drumherum die LoadLibrary-Funktion einzusetzen, wobei die /Include-Variante nicht so schlecht ist.
-
Du sollst eine eigene Init-Funktion machen, hast du das nicht mitbekommen?
Dann entfällt auch die Notwendigkeit für LoadLibrary oder irgendwelche Linker-Switches.