1

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.

Cobra91151
  • 610
  • 4
  • 14
  • @Mat If it's duplicate then please specify the link so I can read it otherwise open my question. – Cobra91151 Sep 18 '17 at 13:13
  • 1
    The link is at the top of the page, below your question title. (You might need to refresh the page.) It is not possible to close as duplicate without supplying at least one link. – Mat Sep 18 '17 at 13:14
  • @Mat I don't think it's the same, the solution is not working in my case. – Cobra91151 Sep 18 '17 at 13:25
  • 2
    Then [edit] your question to show how you applied both solutions in the linked question and how it still doesn't work. – Mat Sep 18 '17 at 13:26
  • @Mat Ok. I have edited the question. – Cobra91151 Sep 18 '17 at 13:49
  • The accepted answer to the linked question clearly states: There are no static signals, so if you want to emit a signal, you need to have a instance. Therefore you need to find a way to gain access of a instance. [The second answer to this question](https://stackoverflow.com/a/18264492/2056452) suggests the use of a `Singleton` for this. Why is that not working for you? You need to have an instance as well, to connect to this signal. No one could listen to it, if you had no instance. – derM - not here for BOT dreams Sep 18 '17 at 13:51
  • @derM Ok. I will check my code again. Thanks. – Cobra91151 Sep 18 '17 at 14:21
  • @derM I have fixed compile errors but it emits nothing. Any ideas? – Cobra91151 Sep 18 '17 at 14:29
  • 1
    The WirelessConnect must be the same in your connect calls and in the signal emits. – Mat Sep 18 '17 at 15:04
  • *Mat* is right. The instances in `static WirelessConnect wirelessConnectObj` and `WirelessConnect *wirelessAPConnect = new WirelessConnect();` are different. Create a `static WirelessConnect* instance()` in your class, that returns a pointer to your static variable. Instead of `new WirelessConnect()` you'll call this method. – derM - not here for BOT dreams Sep 18 '17 at 15:23
  • As this will lead to a `Singleton` and `Singletons` are both awfully easy and awfully dangerous if not used with care, I recommend to read: https://stackoverflow.com/a/138012/2056452 and everything else you can find on the web, that tells you why they are evil. Sometimes though, especially in the context of Qt and UI, it is hard to come by them. – derM - not here for BOT dreams Sep 18 '17 at 15:25
  • **I vote for reopen.** By now your problem is narrowed down and is very specific. You can apply what you found in the linked question, but it becomes obvious that the explanation there is lacking. This, more specific question could be used for a good example. One could write a better answer to the linked question using your question as example, but this would feel odd. – derM - not here for BOT dreams Sep 18 '17 at 15:29
  • @derM I have edited the question. – Cobra91151 Sep 18 '17 at 15:41
  • So what you want is: You **need to have multiple instances**, and when you call your static function, it shall emit the signal in all your instances? – derM - not here for BOT dreams Sep 18 '17 at 15:43
  • @derM No, I meant that only those 2 connects uses static instance, other connects to `WirelessConnect`class uses non static instance. I have initialized `static WirelessConnect wirelessConnectObj;` outside of the class, now it's global. But the same issue, no output. – Cobra91151 Sep 18 '17 at 16:04
  • @derM Maybe the problem is that slots are not static? But it compiles then it should work. – Cobra91151 Sep 18 '17 at 16:07
  • @derM After some time I get `QObject::disconnect: Unexpected null parameter` when connected to the Access Point. I think that's why it doesn't connect signals to slots. – Cobra91151 Sep 18 '17 at 16:27
  • It connects to the wireless network, but nothing is shown in GUI any message, nothing. – Cobra91151 Sep 18 '17 at 16:32
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/154721/discussion-between-derm-and-cobra91151). – derM - not here for BOT dreams Sep 18 '17 at 20:08

1 Answers1

1

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.

Cobra91151
  • 610
  • 4
  • 14