0

Im modifiy my display drivers to get update notifcation sent from the USB port. So far so good, but i got stock on follow:

    GPEFlat::GPEFlat()
{
    PBOOT_ARGS args;
    ULONG      fbSize;
    ULONG      fbOffset;
    ULONG      offsetX;
    ULONG      offsetY;
    BOOL       bFoundArgs = FALSE;

    BOOL        m_MouseDisabled = TRUE;
    HANDLE      m_hAttachEvent = CreateEvent(NULL, FALSE, FALSE, L"MouseAttached");
    HANDLE      m_hDetachEvent = CreateEvent(NULL, FALSE, FALSE, L"MouseDetached");
    HANDLE      m_hCursorThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MouseEventThread, NULL, 0, NULL);

DWORD 
GPEFlat::MouseEventThread(void)
{
    DWORD   rc = TRUE;
    HANDLE  handles[2];
    handles[0] = m_hAttachEvent;
    handles[1] = m_hDetachEvent;

The resulting error is: Error 1 error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'LPTHREAD_START_ROUTINE' drivers\display\vgaflat

So the line : HANDLE m_hCursorThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MouseEventThread, NULL, 0, NULL); Dosnt work. Got some pointers that it may be to non static method. How should i do this? Greetings

  • Thanks for a fast reply. However could you show more in detail how to do this? I will replace my line that occur the problem with your HANDLE m_hcursorThread.... How should i continue? The code typedef, where should i write that? – HappySoftwareDeveloper Oct 04 '13 at 13:27

2 Answers2

0

The MouseEventThread have to be a static function, because a function pointer is not the same as a member function pointer. Static methods can be used as normal function pointers, but non-static member functions can not.

If you need to reference class members, then one very simple solution is to have a static wrapper functions, which takes the instance of the object (this in the constructor) and then calls the actual member function using that instance pointer.

Something like

class GPEFlat
{
    // ...

private:
    static DWORD MouseEventThreadWrapper(LPVOID instance)
        { return reinterpret_cast<GPEFlat*>(instance)->MouseEventThread(); }

    // ...
};

Create the thread with this wrapper function instead, passing this as argument to it:

GPEFlat::GPEFlat()
{
    // ...

    HANDLE      m_hCursorThread = CreateThread(
        NULL, 0, (LPTHREAD_START_ROUTINE)MouseEventThreadWrapper, this, 0, NULL);
}
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • I wrote like this: DWORD MouseEventThreadWrapper; //HANDLE m_hCursorThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)((MyMethodType)MouseEventThread), NULL, 0, NULL); HANDLE m_hCursorThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MouseEventThreadWrapper, this, 0, NULL); Then I get an error, and if I dont declare MouseEvent i get an error according to that. If i declare that i get "no object file" generated – HappySoftwareDeveloper Oct 04 '13 at 13:33
  • @user2605871 Now you're declaring `MouseEventThreadWrapper` as a local *variable* in the constructor. Look again at my answer, I declare it as a static method in the class. – Some programmer dude Oct 04 '13 at 14:03
0

The thing to understand is that functions (including static methods) and non-static methods are different things. CreateEvent expects a function. You must give it that, it will not work with GPEFlat::MouseEventThread because that's a method. What you can do though is give it a function which calls GPEFlat::MouseEventThread. Usually this is done like this

DWORD WINAPI thread_starter(LPVOID that)
{
    return ((GPEFlat*)that)->MouseEventThread();
}

...

CreateThread(NULL, 0, thread_starter, this, 0, NULL);

Note that I pass this to CreateThread, that's very important. CreateThread passes it to the parameter that in thread_starter, which uses that to call the method you wanted to call all along.

john
  • 85,011
  • 4
  • 57
  • 81
  • When i try this i get the error: 'thread_starter': undeclared identifier - pointing ant the CreaThread... and redefinitnion; previously definintion was foremly unknown identifier - pointing at DWORD WINAPI.. – HappySoftwareDeveloper Oct 04 '13 at 13:44
  • @user2605871 thread_starter is a function, you should prototype it like any other function. Put `DWORD WINAPI thread_starter(LPVOID that);` somewhere near the top of your code. – john Oct 04 '13 at 13:55
  • Thanks, no error now. Guess i have to build it all and see how it works! – HappySoftwareDeveloper Oct 04 '13 at 14:17