Emit signal from static function issue
-
- pass
wirelessAPConnect
as thepCallbackContext
parameter toWlanRegisterNotification
- remove
context = NULL;
- (optional but recommended) add, at the beginning of the function,
Q_ASSERT(dynamic_cast<WirelessConnect*>(context));
- change
emit apConnectionComplete();
toqobject_cast<WirelessConnect*>(context)->apConnectionComplete();
- change
emit apConnectionFailed();
toqobject_cast<WirelessConnect*>(context)->apConnectionFailed();
- pass
-
Ok. I have changed to:
void WINAPI WirelessConnect::notificationCallBack(PWLAN_NOTIFICATION_DATA wlanData, PVOID context) { Q_ASSERT(dynamic_cast<WirelessConnect*>(context)); switch (wlanData->NotificationCode) { case wlan_notification_acm_connection_complete: qobject_cast<WirelessConnect*>(context)->apConnectionComplete(); qDebug() << "Connected!"; break; case wlan_notification_acm_connection_attempt_fail: qobject_cast<WirelessConnect*>(context)->apConnectionFailed(); qDebug() << "Failed!"; break; default: break; } } WirelessConnect wirelessAPConnect; dwResult = WlanRegisterNotification(hClient, WLAN_NOTIFICATION_SOURCE_ALL, TRUE, wirelessAPConnect, NULL, NULL, &dwPrevNotif);
And there are a lot of errors:
error: C2355: 'this': can only be referenced inside non-static member functions or non-static data member initializers
error: C2681: 'PVOID': invalid expression type for dynamic_cast
error: C2665: 'qobject_cast': none of the 2 overloads could convert all the argument types
error: C2664: 'DWORD WlanRegisterNotification(HANDLE,DWORD,BOOL,WLAN_NOTIFICATION_CALLBACK,PVOID,PVOID,PDWORD)': cannot convert argument 4 from 'WirelessConnect' to 'WLAN_NOTIFICATION_CALLBACK'
-
Then I changed the code to:
dwResult = WlanRegisterNotification(hClient, WLAN_NOTIFICATION_SOURCE_ALL, TRUE, notificationCallBack, NULL, 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: qobject_cast<WirelessConnect*>(pThis)->apConnectionComplete(); qDebug() << "Connected!"; break; case wlan_notification_acm_connection_attempt_fail: qobject_cast<WirelessConnect*>(pThis)->apConnectionFailed(); qDebug() << "Failed!"; break; default: break; } }
By removing
Q_ASSERT(dynamic_cast<WirelessConnect*>(context));
some error fixed. But some errors still exists: -
These errors are with connect:
connect(wirelessAPConnect, &WirelessConnect::apConnectionComplete, setAPConnection); connect(wirelessAPConnect, &WirelessConnect::apConnectionFailed, setAPConnectionFailed);
How to connect static signals/slots? Thanks.
-
I have fixed the compile errors.
Code:
initialized outside of theWirelessConnect
class to make it global:
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
connect(&wirelessConnectObj, &WirelessConnect::apConnectionComplete, this, &Test::setAPConnection); connect(&wirelessConnectObj, &WirelessConnect::apConnectionFailed, this, &Test::setAPConnectionFailed);
But nothing executes in the slots. It connects to the wireless network, but nothing is shown in GUI any message, nothing.
-
@Cobra91151 Did you check that connect() calls actually succeeded?
Was the callback called?
Also using global variables is bad design. -
@Cobra91151 If connect is not working it prints an error at runtime - is there any?
How to connect depends on your design/architecture.
-
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) { //context = NULL; 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.
-
When using this:
WirelessConnect *pThis = new WirelessConnect(this); dwResult = WlanRegisterNotification(hClient, WLAN_NOTIFICATION_SOURCE_ALL, TRUE, notificationCallBack, pThis, NULL, &dwPrevNotif); void WINAPI WirelessConnect::notificationCallBack(PWLAN_NOTIFICATION_DATA wlanData, PVOID context) { Q_ASSERT(dynamic_cast<WirelessConnect*>(context)); switch (wlanData->NotificationCode) { case wlan_notification_acm_connection_complete: qobject_cast<WirelessConnect*>(context)->apConnectionComplete(); break; case wlan_notification_acm_connection_attempt_fail: qobject_cast<WirelessConnect*>(context)->apConnectionFailed(); break; default: break; } }
I get a lot of errors:
Can you describe your solution more properly? Thanks.