Globale Variablen in Hook-Funktion verwenden



  • Ich habe eine DLL geschrieben die einen Haken bei Windows einhängt um Botschaften vom Mixer-Device abzufangen, und dann darauf zu reagieren. Nun möchte ich aber in der von Windows aufgerufenen Hook-Funktion Variablen verwenden die ich vorm setzen des Hooks an die DLL übergeben habe.

    Allerdings sind die in der DLL global definierten Variablen dann ständig NULL.
    Das liegt wahrscheinlich daran, daß jedesmal wenn die Hook-Funktion aufgerufen wird, dafür ein neuer Adressraum angelegt wird.(Denke ich 😕 )

    Wie könnte man der Hookfunktion sonst die Variablen oder deren Adressen mitteilen???



  • Vielleicht sollte ich mich etwas konkreter ausdrücken.
    Also ersmal Quelltext:

    #include <vcl.h>
    #include <windows.h>
    #include <Mmsystem.h>
    #pragma hdrstop
    
    #pragma argsused
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
            return 1;
    }
    
    HMIXER hmx = 0;
    MMRESULT result;
    UINT mid = 0;
    bool fix=false;
    DWORD globValueMaster, globValueWave, globValueLineIn;
    void setVolume(DWORD value, DWORD line);
    HHOOK   hHook;   /* Handle auf die Hook-Funktion */
    
    LRESULT CALLBACK Hook(int nCode, WPARAM wParam, LPARAM lParam)
    {
      if(nCode==HC_ACTION){
             MSG *pMsg=(MSG*)lParam;
             if(pMsg->message == MM_MIXM_CONTROL_CHANGE){
                 setVolume(globValueMaster, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS);// die 3 glob... Variablen
                 setVolume(globValueWave, MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT);//sind hier
                 setVolume(globValueLineIn, MIXERLINE_COMPONENTTYPE_SRC_LINE);//immer 0
             }
      return 1;
      }
      return CallNextHookEx(hHook, nCode, wParam, lParam);
    }
    
    extern "C" __declspec (dllexport) unsigned long MXOpen(unsigned int valueMaster,
                               unsigned int valueWave, unsigned int valueLineIn,
                               char mask)
    {
      HMODULE mh=GetModuleHandle("Project2.dll");
      result = mixerOpen(&hmx, mid, (DWORD)(UINT)Application->Handle, 0L, CALLBACK_WINDOW);
      if(mask & 1){
        setVolume((DWORD)valueMaster, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS);
        globValueMaster=valueMaster;
      }
      if(mask & 2){
        setVolume((DWORD)valueWave, MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT);
        globValueWave=valueWave;
      }
      if(mask & 4){
        setVolume((DWORD)valueLineIn, MIXERLINE_COMPONENTTYPE_SRC_LINE);
        globValueLineIn=valueLineIn;
      }
    
      fix=true;
      HOOKPROC  lpHook;
      //	lpHook = (HOOKPROC)GetProcAddress(hDLL, "Hook");
      hHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)Hook, mh, 0);
    
    return (unsigned long)hHook;
    }
    
    void setVolume(DWORD value, DWORD line){
            MIXERCONTROLDETAILS mcd={0};
    	MIXERCONTROLDETAILS_UNSIGNED mcdu={0};
    
            MIXERLINE ml = {0};
            ml.cbStruct = sizeof(MIXERLINE);
            if (line == MIXERLINE_COMPONENTTYPE_SRC_LINE){
              ml.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
              mixerGetLineInfo((HMIXEROBJ) hmx, &ml, MIXER_GETLINEINFOF_COMPONENTTYPE);
              unsigned long maxSources=ml.cConnections;
              unsigned int i=0;
              while(i<maxSources && ml.dwComponentType != MIXERLINE_COMPONENTTYPE_SRC_LINE){
                ml.dwSource=i;
                mixerGetLineInfo((HMIXEROBJ) hmx, &ml, MIXER_GETLINEINFOF_SOURCE);
                i++;
              }
            }
            else{
              ml.dwComponentType = line;
              result = mixerGetLineInfo((HMIXEROBJ) hmx, &ml, MIXER_GETLINEINFOF_COMPONENTTYPE);
            }
    
            MIXERLINECONTROLS mlc = {0};
            MIXERCONTROL mc = {0};
            mlc.cbStruct = sizeof(MIXERLINECONTROLS);
            mlc.dwLineID = ml.dwLineID;
            mlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
            mlc.cControls = 1;
            mlc.pamxctrl = &mc;
            mlc.cbmxctrl = sizeof(MIXERCONTROL);
            result = mixerGetLineControls((HMIXEROBJ) hmx, &mlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);
    
    	mcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
    	mcd.dwControlID = mc.dwControlID;
    	mcd.cChannels = 1;
    	mcd.hwndOwner = 0;
    	mcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
    	mcd.paDetails = &mcdu;
    
    	mcdu.dwValue =value;
            result=	mixerSetControlDetails((HMIXEROBJ) hmx, &mcd, MIXER_SETCONTROLDETAILSF_VALUE);
    
    }
    
    extern "C" __declspec (dllexport) int MXClose(unsigned long handle)
    {
      fix=false;
      UnhookWindowsHookEx((HHOOK)handle);
      return mixerClose(hmx);
    }
    

    Die 3 Variablen sind da beim ausführen immer 0. Beim debuggen allerdings nicht.
    Hat jemand mehr Ahnung als ich, die Funktion setVolume() findet er doch auch.



  • Mit MSVC++ kannst du ein Datensegment mit jeder Instanz der DLL teilen. siehe http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/_core_how_do_i_share_data_in_my_dll_with_an_application_or_with_other_dlls.3f.asp
    Tipp:
    Sag dem Linker auch über eine Präprozessoranweisung Bescheid:

    //---------------
    //  shared data
    //---------------
    #pragma data_seg("Shared")
    HHOOK hHook=NULL;
    #pragma data_seg()
    #pragma comment(linker, "/section:Shared,RWS")
    

    PS: im o.a. Link wird auch eine Alternative mit Memory Mapped Files erwähnt



  • Danke das hat mir sehr geholfen. 👍
    Ich mußte das zwar noch etwas auf Borland abstimmen, aber jetzt läufts super.
    Ich habe im Netz nachgeschaut und es so ähnlich wie dort gelöst.

    Diese Dateien dem Projekt mit hinzugefügt und die SharedData.h inluded:

    SharedData.cpp:

    #pragma option -zR_SHSEG
    #pragma option -zT_SHCLASS
    
    #include "windows.h"
    
    HHOOK   hHook=NULL;   /* Handle auf die Hook-Funktion */
    DWORD globValueMaster=0;
    DWORD globValueWave=0;
    DWORD globValueLineIn=0;
    

    SharedData.h:

    extern HHOOK   hHook;
    extern DWORD globValueMaster;
    extern DWORD globValueWave;
    extern DWORD globValueLineIn;
    

    Shared.def:

    LIBRARY      PROJECT2
    
    SEGMENTS
    	_SHSEG CLASS '_SHCLASS' SHARED
    

    🙂 😃 🙂


Anmelden zum Antworten