Emit signal from static function issue

629 views Asked by At

I want to emit signal when wlan connection has been registered from static notificationCallBack function.

Code:

WirelessConnect.h

static void WINAPI notificationCallBack(PWLAN_NOTIFICATION_DATA wlanData, PVOID context);

WirelessConnect.cpp

DWORD dwResult = 0;
dwResult = WlanRegisterNotification(hClient, WLAN_NOTIFICATION_SOURCE_ALL, TRUE, notificationCallBack, NULL, NULL, &dwPrevNotif);

void WINAPI WirelessConnect::notificationCallBack(PWLAN_NOTIFICATION_DATA wlanData, PVOID context)
{
    context = NULL;
    switch (wlanData->NotificationCode) {
        case wlan_notification_acm_connection_complete:
            emit apConnectionComplete();
            qDebug() << "Connected!";
        break;

        case wlan_notification_acm_connection_attempt_fail:
            emit apConnectionFailed();
            qDebug() << "Failed!";
        break;

        default:
            break;
    }
}

Test .cpp:

WirelessConnect *wirelessAPConnect = new WirelessConnect();
connect(wirelessAPConnect, &WirelessConnect::apConnectionComplete, setAPConnection);
connect(wirelessAPConnect, &WirelessConnect::apConnectionFailed, setAPConnectionFailed);

The problem is error: C2355: 'this': can only be referenced inside non-static member functions or non-static data member initializers.

So how to emit signal from the static function, for example to display QMessageBox about the wlan connection in Test class?

Solutions from the link above not working:

1 Method: notificationCallBack(PWLAN_NOTIFICATION_DATA wlanData, PVOID context) function require only 2 parameters PWLAN_NOTIFICATION_DATA wlanData and PVOID context and not a reference to the class as parameter

2 Method: lead to error: C3867: 'WirelessConnect::apConnectionComplete': non-standard syntax; use '&' to create a pointer to member in the connect: connect(wirelessAPConnect, WirelessConnect::apConnectionComplete, this, &Test::setAPConnection);

I have fixed the compile errors with the 2 method but it emits nothing.

Code:

WirelessConnect.cpp

static WirelessConnect wirelessConnectObj;

void WINAPI WirelessConnect::notificationCallBack(PWLAN_NOTIFICATION_DATA wlanData, PVOID context)
{
    context = NULL;
    switch (wlanData->NotificationCode) {
        case wlan_notification_acm_connection_complete:
            wirelessConnectObj.apConnectionComplete();
            qDebug() << "Connected!";
        break;

        case wlan_notification_acm_connection_attempt_fail:
            wirelessConnectObj.apConnectionFailed();
            qDebug() << "Failed!";
        break;

        default:
            break;
    }
}

dwResult = WlanRegisterNotification(hClient, WLAN_NOTIFICATION_SOURCE_ALL, TRUE, notificationCallBack, NULL, NULL, &dwPrevNotif);

Test.cpp

WirelessConnect *wirelessAPConnect = new WirelessConnect();
connect(wirelessAPConnect, &WirelessConnect::apConnectionComplete, this, &Test::setAPConnection);
connect(wirelessAPConnect, &WirelessConnect::apConnectionFailed, this, &Test::setAPConnectionFailed);

No compile errors and setAPConnection doesn't executes.

I think static WirelessConnect wirelessConnectObj; is NULL and it execute nothing. When I use static WirelessConnect *wirelessConnectObj; as pointer after app connect to the Access Point then application crashes.

When initialize static WirelessConnect *wirelessConnectObj = new WirelessConnect(); the application works but no signal/slot execution.

Edited:

WirelessConnect class manages also other non static wlan functions, which are connected to signals and slots. So I can't delete wirelessAPConnect object and use only static object. I have intialized static WirelessConnect wirelessConnectObj; in Test also and connect it:

connect(&wirelessConnectObj, &WirelessConnect::apConnectionComplete, this, &Test::setAPConnection);
connect(&wirelessConnectObj, &WirelessConnect::apConnectionFailed, this, &Test::setAPConnectionFailed);

The output is the same - nothing. I think, it's because I have created 2 different static instances of WirelessConnect class. I need to have only one static instance of the WirelessConnect which should be global to send signal and connect them in Test.

1

There are 1 answers

0
Cobra91151 On BEST ANSWER

I have fixed the issue:

I set this to the function:

WlanRegisterNotification(hClient, WLAN_NOTIFICATION_SOURCE_ALL, TRUE, notificationCallBack, this, NULL, &dwPrevNotif);

void WINAPI WirelessConnect::notificationCallBack(PWLAN_NOTIFICATION_DATA wlanData, PVOID context)
{
    WirelessConnect *pThis = (WirelessConnect*) context;
    switch (wlanData->NotificationCode) {
        case wlan_notification_acm_connection_complete:
            pThis->apConnectionComplete();
            qDebug() << "Connected!";
        break;

        case wlan_notification_acm_connection_attempt_fail:
            pThis->apConnectionFailed();
            qDebug() << "Failed!";
        break;

        default:
            break;
    }
}

Then connect it as not static instance:

connect(wirelessAPConnect, &WirelessConnect::apConnectionComplete, this, &Test::setAPConnection); 
connect(wirelessAPConnect, &WirelessConnect::apConnectionFailed, this, &Test::setAPConnectionFailed);

So I don't need the static global instance anymore and it works now.

Edited:

After some diagnostics (connecting/disconnecting from Access Points), the solution lead to application crash.