Link to home
Start Free TrialLog in
Avatar of openujs
openujs

asked on

Callback function and global Variable

ok i have an app similiar to one down here....I am trying to access global variable from a call back function after modifying the variable before Callback function is invoked, why didn;t i get the updated value?

//Global variable
static int gNum = 5;

main( void )
{
  initialize();
}

void initialize()
{
  gNum = 5;
  InvokeCallback( CallbackFunc );//Calls CallbackFunc
}

static void CallbackFunc( void ** ptr)//this parameter is irrelevant to the question
{
  //Here I am trying to access gNum, I was expecting gNum to be 5, but i got 0.????
 cout<<gNum;
}
Avatar of MeiaDose
MeiaDose

1st. you initialize gNum with the value of 5 and it is a global variable. So why do you do gNum=5 in your initialize function?

Apart of this question its a weird bug...

Maybe your afecting gNum somewhere else?...

Avatar of openujs

ASKER

oh sorry i had a typo..........
gNum is initialized as 0 at the very top.

//Global variable
static int gNum = 0;//not 5

I wrote this code and the value of "var" doesn´t change.

"
static int var = 0;

int CALLBACK myCallBack(){
      int i= var;
      return i;
}

void main(){
      var = 5;
      myCallBack();
}
"
I have one more question though...

Where did you found this function?
"
 InvokeCallback( CallbackFunc );//Calls CallbackFunc
"

I've searched the MSDN and i didn't found any reference to it...


Avatar of openujs

ASKER

InvokeCallBack( CallbackFunc) is just a function i created, InvokeCallBack function invokes CallbackFunc()..I know, val of var should be 5, i keep getting 0, not sure why.
ok.

run the code that i've posted and tell me is the value of var is 5 inside the callback function...

Another tip:

just for debug, change "static int gNum = 5;" to "const static int gNum = 5;"

This way if anything is trying to change the value of gNum you sould notice!

Tell me is this worked please :)

Good Luck!
By the way, post your InvokeCallBack function please.

Thank you.
Avatar of openujs

ASKER

No value is still 0,  if u make gNum const static int, then i will have compiler error when i am trying to modify its value from 0 to 5. My whole point is to modfy the value and pass it to the callback function.
Avatar of openujs

ASKER

No value is still 0,  if u make gNum const static int, then i will have compiler error when i am trying to modify its value from 0 to 5. My whole point is to modfy the value and pass it to the callback function.
Try to switch off all optimizations in the compiler options.
void initialize()
{
 gNum = 5;
 CallbackFunc(NULL);
}

0 or 5 ?
The use of global variables in this way has been deprecated.

Use an unnamed namespace instead. Adherence to the C++ standard is always recommended.

//Global variable
namespace
{
    int gNum = 5;
}

If you want to modify it's value from another compilation unit provide explicit accessor functions.
i think the problem could be inside invokecallback.
please post code.
Avatar of openujs

ASKER

Ok,,,,I am posting my actual code,  this application is actually a dll.
When another Dialog application opens, it calls the method of this dll, method called installhook( HWND handle), and passes it handle to this dll.Now inside the installhook , I am calling SetWindowsHookEx(...) this is Win API, it calls my callback method, called hookproc. I am trying to pass that HWND handle to this callback, so I declared a global HWND variable, initialized it to NULL, but inside my callback function, the handle is still NULL, even though this global HWND variable is set to be the new Window handle( handle of the dialog app window).
Here is the code........................
Also, the callback function only takes 3 params, i can not pass HWND, so i was using it as global to pass it to Callback func.

#include "stdafx.h"
#include <afxdllx.h>
#include "HookEx.h"


//Shared data among all instances
#pragma data_seg(".HOOKDATA")//Shared data among all instances.
HHOOK hook = NULL;
static HWND h = NULL;
#pragma data_seg()
#pragma comment( linker, "/SECTION:.HOOKDATA, RWS")
HINSTANCE hInst = NULL;

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

static AFX_EXTENSION_MODULE HookExDLL = { NULL, NULL };

extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
      // Remove this if you use lpReserved
      UNREFERENCED_PARAMETER(lpReserved);

      if (dwReason == DLL_PROCESS_ATTACH)
      {
            TRACE0("HOOKEX.DLL Initializing!\n");
            
            // Extension DLL one-time initialization
            if (!AfxInitExtensionModule(HookExDLL, hInstance))
                  return 0;

            // Insert this DLL into the resource chain
            // NOTE: If this Extension DLL is being implicitly linked to by
            //  an MFC Regular DLL (such as an ActiveX Control)
            //  instead of an MFC application, then you will want to
            //  remove this line from DllMain and put it in a separate
            //  function exported from this Extension DLL.  The Regular DLL
            //  that uses this Extension DLL should then explicitly call that
            //  function to initialize this Extension DLL.  Otherwise,
            //  the CDynLinkLibrary object will not be attached to the
            //  Regular DLL's resource chain, and serious problems will
            //  result.

            new CDynLinkLibrary(HookExDLL);
      }
      else if (dwReason == DLL_PROCESS_DETACH)
      {
            TRACE0("HOOKEX.DLL Terminating!\n");
            // Terminate the library before destructors are called
            AfxTermExtensionModule(HookExDLL);
      }
      hInst = hInstance;
      return 1;   // ok
}


KEYDLL3_API void  installhook( HWND handle )
{

      if( handle == NULL ) {
            MessageBox( NULL, "NULL Window Handle used", "Error!", MB_OK );
            return;
      }

      hook = NULL;
      h = handle;
      if( hInst == NULL )        MessageBox(NULL,"NULL Instance","Error!",MB_OK);
      hook = SetWindowsHookEx( WH_KEYBOARD, hookproc, hInst, NULL );
      if( hook == NULL )       MessageBox(NULL,"Unable to install hook","Error 101!",MB_OK);
      
}


KEYDLL3_API void removehook()
{
      UnhookWindowsHookEx( hook );
}

KEYDLL3_API LRESULT CALLBACK hookproc( int ncode, WPARAM wparam,LPARAM lparam)
{
      if( ncode >= 0 ){
            if( ( lparam & 0x80000000 ) == 0x00000000 ){//Only when it is pressed not released
                  
//h is NULL all the time,,,Here is the problem#########
if( h == NULL) MessageBox(NULL,"Unable to install hook","Error 102!",MB_OK);
                  BOOL bRet =      PostMessage( h, WM_USER + 755, wparam, lparam );
      
            }
      }
      return ( CallNextHookEx(hook,ncode, wparam,lparam) );//pass control to next hook in the hook chain.

}

Are you sure that .HOOKDATA is really shared?
I compiled the code (with some changes).
As I said before, linker does not make .HOOKDATA  as a shared segment.
I'm trying to understand why...
Avatar of openujs

ASKER

GlommyFrair...ok...but .HOOKDATA is really nothing to do with my problem..but u can experiment if u like to...:)
>.HOOKDATA is really nothing to do with my problem
Are you sure?

Try the next code.

#pragma data_seg("myshare")//Shared data among all instances.
__declspec(allocate("myshare")) HHOOK hook;
__declspec(allocate("myshare")) HWND h;
#pragma data_seg()
#pragma comment(linker, "/SECTION:myshare,RWS")
Avatar of openujs

ASKER

Yes,,it works!!... u r the man!! thanks a lot:)
ASKER CERTIFIED SOLUTION
Avatar of GloomyFriar
GloomyFriar

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of openujs

ASKER

HeHe....no points for u..just a plain o thank u:)

ok i will add 10 more bonus points.