Thread: Static function pointer linker error

  1. #1
    Registered User
    Join Date
    Mar 2006
    Location
    USA::Colorado
    Posts
    155

    Static function pointer linker error

    Hello all,

    I'm writing a class with a static function pointer in it, however I'm getting a linker error saying that it is an unresolved external symbol. Here's my code:

    BindHook.h
    Code:
    #ifndef BINDHOOK
    #define BINDHOOK
    
    #include <Windows.h>
    
    class BindHook
    {
    public:
    	static HHOOK kbHook, msHook;
    
    	static bool (*onKeyEvent)(int vkey, WPARAM msg);
    	
    	static void InitHooks();
    	static void StopHooks();
    
    	static LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
    	static LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam);
    };
    
    #endif
    BindHook.cpp
    Code:
    #include "BindHook.h"
    
    bool (BindHook::*onKeyEvent)(int vkey, WPARAM msg) = NULL;
    
    HHOOK BindHook::kbHook = 0;
    HHOOK BindHook::msHook = 0;
    
    LRESULT CALLBACK BindHook::KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
    	if (nCode != HC_ACTION)
    		return CallNextHookEx(kbHook, nCode, wParam, lParam);
    	
    	//get the struct
    	PKBDLLHOOKSTRUCT kb = (PKBDLLHOOKSTRUCT)lParam;
    
    	//injected key?
    	bool inj = ((kb->flags & 0x00000010) == 16);
    
    	//call fn's
    	if ((wParam == WM_KEYDOWN || wParam == WM_KEYUP) && !inj)
    		if (onKeyEvent(kb->vkCode, wParam))
    			return true;
    
    	return CallNextHookEx(kbHook, nCode, wParam, lParam);
    }
    
    LRESULT CALLBACK BindHook::MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
    	if (nCode != HC_ACTION)
    		return CallNextHookEx(msHook, nCode, wParam, lParam);
    
    	PMSLLHOOKSTRUCT ms = (PMSLLHOOKSTRUCT)lParam;
    	bool inj = ((ms->flags & 0x00000001) == 1);
    	int vk = -1;
    
    	//determine VKEY
    	switch (wParam)
    	{
    	case WM_LBUTTONUP: case WM_LBUTTONDOWN:
    		vk = VK_LBUTTON;
    		break;
    	case WM_RBUTTONUP: case WM_RBUTTONDOWN:
    		vk = VK_LBUTTON;
    		break;
    	case WM_MBUTTONUP: case WM_MBUTTONDOWN:
    		vk = VK_LBUTTON;
    		break;
    	case WM_XBUTTONUP: case WM_XBUTTONDOWN:
    		vk = ((ms->mouseData >> 16 ) & 0xFFFF) == 1 ? VK_XBUTTON1 : VK_XBUTTON2;
    		break;
    	}
    
    	switch (wParam)
    	{
    	case WM_LBUTTONUP:
    	case WM_RBUTTONUP:
    	case WM_MBUTTONUP:
    	case WM_XBUTTONUP:
    		if (!inj)
    			if(onKeyEvent(vk, WM_KEYUP))
    				return true;
    		break;
    	case WM_LBUTTONDOWN:
    	case WM_RBUTTONDOWN:
    	case WM_MBUTTONDOWN:
    	case WM_XBUTTONDOWN:
    		if (!inj)
    			if(onKeyEvent(vk, WM_KEYDOWN))
    				return true;
    		break;
    	}
    
    	return CallNextHookEx(msHook, nCode, wParam, lParam);
    }
    
    void BindHook::InitHooks()
    {
    	kbHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)KeyboardProc, NULL, NULL);
    }
    
    void BindHook::StopHooks()
    {
    	UnhookWindowsHookEx(kbHook);
    }
    The specific Error:
    Code:
    Error	1	error LNK2001: unresolved external symbol "public: static bool (__cdecl* BindHook::onKeyEvent)(int,unsigned int)" (?onKeyEvent@BindHook@@2P6A_NHI@ZA)	C:\[...]\BindHook.obj	BindSystem_Console
    Any help would be greatly appreciated.

    Thanks,

    -Matt
    ~guitarist809~

  2. #2
    Just a pushpin. bernt's Avatar
    Join Date
    May 2009
    Posts
    426
    Code:
    bool (BindHook::*onKeyEvent)(int vkey, WPARAM msg) = NULL;
    This should be
    Code:
    bool (*(BindHook::onKeyEvent))(int vkey, WPARAM msg) = NULL;
    I don't know how to explain this particular function pointer rule. I think that perhaps BindHook::*onKeyEvent is the type, and *(BindHook:: onKeyEvent) is the variable itself (that's just speculation though).

    The situation becomes much clearer if you use typedefs (I'd recommend the typedefs route any time you need function pointers):
    Code:
    //in the header
    class BindHook
    {
        ...
        typedef bool (*KeyEventFunc)(int vkey, WPARAM msg);
        static KeyEventFunc onKeyEvent;
        ...
    };
    
    //and in the code
    BindHook::KeyEventFunc BindHook::onKeyEvent = NULL;
    Consider this post signed

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Even better:
    Code:
    typedef bool (KeyEventFunc_t)(int vkey, WPARAM msg);
    KeyEventFunc_t* KeyEventFunc;
    As with any static variable, you need to define them in a source file (and only once):
    Code:
    KeyEventFunc_t* MyClass::KeyEventFunc;
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Linker error on static linking to third party lib
    By System_159 in forum Windows Programming
    Replies: 1
    Last Post: 06-30-2011, 06:54 PM
  2. linker error with static member...
    By m37h0d in forum C++ Programming
    Replies: 10
    Last Post: 05-25-2011, 02:27 PM
  3. static declaration creates linker error
    By black_spot1984 in forum C++ Programming
    Replies: 1
    Last Post: 11-04-2008, 10:58 AM
  4. static instance variable linker error
    By animeaholic in forum C++ Programming
    Replies: 4
    Last Post: 01-23-2007, 09:50 PM
  5. linker error, using static member
    By Chiel in forum C++ Programming
    Replies: 6
    Last Post: 06-28-2003, 08:40 PM