Dll globale Variable verschwindet bei "Focusverlust" des Fensters
-
Ich habe folgendes Problem:
Ich habe eine Dll, diese hat 3 FUnktionen:
Diese Variable hat globale Variablen, die von einer exportierten Funktion gefüllt werden. Eine Funktion (MouseProc) reagiert auf Events und benutzt dabei die globalen Variablen.Nun passiert allerdings folgendes:
Wenn das Fenster, welches die dll aufgerufen hat den Fokus hat, läuft alles wunderbar, aber sobald es den Fokus verliert, verlieren die globalen Variablen ihre Werte. (Sprich wenn ich z.B. eine globale INteger Variable = 5 habe, ist sie, wenn das Fenster keinen Fokus hat = 0).Wenn das Fenster den Fokus wieder bekommt, klappt alles wieder (die Variablen haben ihren alten Wert).
Zuerst dachte ich es läge an den Pointer. Ich hatte nämlich zunächst bei der Zuweisung der globalen Variablen nur Pointer auf Objekte verwiesen, die im Speicherbereich des Fensters liegen. Allerdings tritt das gleiche Problem auf, wenn ich "normale" Variablen benutze.
Woran liegt das?
Welchen Speicherbereich nutz Eine globale dll?MFG
Ace
-
Wenn das Fenster, welches die dll aufgerufen hat
Was soll das heißen? Ein Fenster ruft keine DLL auf.
Ich vermute mal du hast einen systemweiten Hook installiert. Hierbei sollte dir klar sein, daß die DLL in jedem Prozess ihren eigenen Satz Variablen bekommt, das erklärt das Verhalten, was du beschreibst. Was du benötigst ist ein shared data segment, schau ins WinAPI Faq. Da gibts nen Thread zum Thema Keyboard Hook, wo das ganze demonstriert wird.
-
#pragma data_seg("SensHook") tSensivityBar* Bar; bool isCtrlDown;//, isShiftDown; #pragma data_seg() #pragma comment( linker ,"/section:Shared,RWS")Es funktioniert nicht und ich bekomme folgende Warnung:
[C++ Warning] quellcode_new.cpp(12): W8094 Incorrect use of #pragma comment( <type> [,"string"] )
-
#pragma data_seg("SensHook") tSensivityBar* Bar; bool isCtrlDown;//, isShiftDown; #pragma data_seg() #pragma comment( linker ,"/section:Shared,RWS")#pragma data_seg("SensHook") tSensivityBar* Bar; bool isCtrlDown;//, isShiftDown; #pragma data_seg() #pragma comment( linker ,"/section:SensHook,RWS")geändert
-
Sry tripple Post:
Geht aber immmer noch nicht.
-
Muss ich auch das HookHandle in das Data Segment schreiben?
Es funktioniert nämlich immer noch nicht.
-
// Weise den Compiler an, die Variable hWindow in einem // separaten Abschnitt namens Shared unterzubringen // Darüber hinaus ist dann auch noch dem Linker mitzuteilen, // dass die Daten in diesem Abschnitt von allen Instanzen // dieser Anwendung gemeinsam verwendet werden sollen. // Ganz wichtig dabei ist, dass die Variablen initialisiert // sein müssen. #pragma data_seg ("Shared") HWND hWindow = 0 ; #pragma data_seg () // Weise den Compilern, den Abschnitt Shared als lesbar, // beschreibbar und zur gemeinsamen Verwendung zu deklarieren - "RSW". #pragma comment (linker, "/section:Shared,RWS")
-
Da mir ja sonst keiner glaubt:
kompletter Quellcode einer Test-dll://--------------------------------------------------------------------------- #include <windows.h> #pragma hdrstop #pragma argsused #pragma data_seg(".SensHook") int testVar = 5; #pragma data_seg() #pragma comment(linker ,"/section:.SensHook,RWS") HINSTANCE hDllInstance ; HHOOK KeyHookHandle; int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved){ hDllInstance = hinst; return 1; } LRESULT CALLBACK KeyHookProc(int nCode,WPARAM wParam,LPARAM lParam){ if(nCode==HC_ACTION){ if(wParam == VK_CONTROL){ if((lParam & (1 << 31)) == 0){//Bedingung für WM_KEYDOWN if((lParam & (1 << 30)) == 0){//checkt ob Taste gedrückt gehalten wird if(testVar == 10){ Beep(500,100); }else{ if(testVar == 5){ Beep(1000,100); }else{ Beep(1000,100); Beep(500,100); } } } } } } return(CallNextHookEx(KeyHookHandle, nCode, wParam, lParam)); } //--------------------------------------------------------------------------- __declspec (dllexport) bool InstallHook(void){ testVar = 10; KeyHookHandle = NULL; KeyHookHandle = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyHookProc, hDllInstance,NULL); if (KeyHookHandle == NULL) { return false; }else{ return true; } } //--------------------------------------------------------------------------- __declspec (dllexport) int UninstallHook(void){ if(UnhookWindowsHookEx(KeyHookHandle)){ return true; }else{ return false; } }Dieser Code macht folgendes:
Im Data Segment ".SensHook" wird die Varible testVar angelegt. Die wird mit dem Wert 5 initialisiert. Beim Aufruf der Funktion InstallHook wird die Variable auf den Wert 10 geändert.
Wenn ich nun die Funktion InstallHook aufrufe passiert folgendes:
Wenn das Fenster, welches die Funktion aufgerufen hat, den Fokus hat und man die STRG - Taste drückt, hört man ein kurzes tiefes Piepen, was bedeutet das die Variable = 10 ist. Soweit stimmt alles.
Wenn ich nun in ein anderes Fenster wechsle und wieder die STRG - Taste drücke, höre ich ein kurzes hohes Piepen, was bedeutet, das die Varible den Wert 5 hat. Ich schließe daraus, das sie den Wert hat, mit dem sie initialisiert wurde, unabhängig davon, dass sie eigentlich schon geändert wurde (beim Aufruf von InstallHook()).Woran liegt das?????
-
liegt an deinem komischen compiler der mit dem pragma statement nicht klarkommt. nimm mal vs, dann funzt es.
-
Das ist aber sehr komisch.
Ich nutze den Borland C++ Builder 6 und hatte noch nie Probleme.Aber nun gut nehm ich halt Visual Studio
-
Reicht da die aktuelle Express Edition?
-
Die dll zu erstellen geht mit Visual C++ 2008 Express prima, allerdings weiß ich nicht, wie ich die dll jetzt laden soll.
Ich habe in der Hauptanwendung folgendes reingeschrieben:
// test3.cpp: Hauptprojektdatei. #include "stdafx.h" #include "Form1.h" //#pragma comment(lib, "test.lib") __declspec(dllimport) bool InstallHook(void) ; __declspec(dllimport) int UninstallHook() ; using namespace test3; [STAThreadAttribute] int main(array<System::String ^> ^args) { // Aktivieren visueller Effekte von Windows XP, bevor Steuerelemente erstellt werden Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); // Hauptfenster erstellen und ausführen Application::Run(gcnew Form1()); InstallHook(); return 0; }So konnte ich die dll bei Borland C++ Builder laden.
Ich bekomme allerdings diese Fehler:
1>------ Erstellen gestartet: Projekt: test3, Konfiguration: Debug Win32 ------ 1>Kompilieren... 1>test3.cpp 1>.\test3.cpp(7) : warning C4272: "InstallHook": Ist als __declspec(dllimport) markiert. Beim Importieren einer Funktion muss eine systemeigene Aufrufkonvention angegeben werden. 1>.\test3.cpp(8) : warning C4272: "UninstallHook": Ist als __declspec(dllimport) markiert. Beim Importieren einer Funktion muss eine systemeigene Aufrufkonvention angegeben werden. 1>Verknüpfen... 1>test3.obj : error LNK2028: Nicht aufgelöstes Token (0A000007) ""bool __clrcall InstallHook(void)" (?InstallHook@@$$FYM_NXZ)", auf das in Funktion ""int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@System@@@Z)" verwiesen wird. 1>test3.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""bool __clrcall InstallHook(void)" (?InstallHook@@$$FYM_NXZ)" in Funktion ""int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP$01AP$AAVString@System@@@Z)". 1>C:\Dokumente und Einstellungen\Besitzer\Eigene Dateien\Visual Studio 2008\Projects\test3\Debug\test3.exe : fatal error LNK1120: 2 nicht aufgelöste externe Verweise. 1>Das Buildprotokoll wurde unter "file://c:\Dokumente und Einstellungen\Besitzer\Eigene Dateien\Visual Studio 2008\Projects\test3\test3\Debug\BuildLog.htm" gespeichert. 1>test3 - 3 Fehler, 2 Warnung(en) ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========
-