I am using KDNSSD in my qt cmake project with C++ in Windows 11 (MSVC) backed by bonjour it discovers and registers the device in debug mode but when I compile the project in Release mode it no longer works, The Logs I have seen in different mode are,
Debug Mode
Both Browse and Register:
qt.core.qobject.connect: QObject::connect: Connecting from COMPAT signal (QSocketNotifier::activated(int))
Release Mode
For Service Browse:
QObject::setParent: Cannot set parent, new parent is in a different thread
QSocketNotifier: Can only be used with threads started with QThread
qt.core.qobject.connect: QObject::connect: Connecting from COMPAT signal (QSocketNotifier::activated(int))
QObject::startTimer: Timers can only be used with threads started with QThread
For Register:
QSocketNotifier: Can only be used with threads started with QThread
qt.core.qobject.connect: QObject::connect: Connecting from COMPAT signal (QSocketNotifier::activated(int))
This Log shows in all Build
Exception thrown at 0x00007FFFFA004B2C (KernelBase.dll) in clipbird.exe: 0x8001010D: An outgoing call cannot be made since the application is dispatching an input-synchronous call.
onecore\com\combase\dcomrem\giptbl.cxx(1796)\combase.dll!00007FFFFC2054EC: (caller: 00007FFFFC21DE1D) ReturnHr(1) tid(3dec) 8000FFFF Catastrophic failure
onecore\com\combase\objact\actvator.cxx(1097)\combase.dll!00007FFFFC21DEB0: (caller: 00007FFFFC280364) ReturnHr(2) tid(3dec) 8000FFFF Catastrophic failure
First of all, I have not using Threads Directly, and When I see the line in KDNSSD Source code it uses old SIGNAL and SLOT so the Connecting from COMPAT signal seems to be appropriate But I have no idea about the other Logs, especially in Release Mode. My whole project located at github especially service register and service browser
Service Register
/**
* @brief Construct a new Discovery Register object
*
* @param parent Parent object
*/
Register::Register(QObject* parent) : QObject(parent) {
this->service = new KDNSSD::PublicService();
this->service->setParent(this);
// connect the signals to the slots
const auto signal_r = &KDNSSD::PublicService::published;
const auto slot_r = &Register::OnServiceRegistered;
connect(this->service, signal_r, this, slot_r);
}
/**
* @brief Register the service
*
* @param callback Callback function to be called
* when service Registered
*/
void Register::registerServiceAsync() {
// Set the service name & other details
this->service->setServiceName(constants::getMDnsServiceName().c_str());
this->service->setType(constants::getMDnsServiceType().c_str());
this->service->setPort(this->getPort());
// publish the service Asynchronously
this->service->publishAsync();
}
/**
* @brief Stop the server
*/
void Register::unregisterService() {
this->service->stop();
}
Service Browser
/**
* @brief Construct a new Discovery Discover object
*
* @param parent Parent object
*/
Discover::Discover(QObject* parent) : QObject(parent) {
this->m_browser = new KDNSSD::ServiceBrowser(constants::getMDnsServiceType().c_str());
this->m_browser->setParent(this);
}
/// @brief On Service Found
void Discover::OnServiceFound(KDNSSD::RemoteService::Ptr service) {
// get the name of the device & lambda callback
const auto myDevice = QString::fromStdString(constants::getMDnsServiceName());
const auto callback = [&, service](const QHostInfo& info) {
if (info.error() != QHostInfo::NoError || info.addresses().isEmpty()) {
emit this->OnErrorOccurred(LOG("Unable to resolve service"));
return;
}
auto host = info.addresses().first();
auto port = quint16(service->port());
this->onServerAdded({host, port});
};
// resolve the service
if (!service->resolve()) {
emit this->OnErrorOccurred(LOG("Unable to resolve service"));
return;
}
// check if the service is mine
if (service->serviceName() == myDevice) {
return;
}
// lookup the host
QHostInfo::lookupHost(service->hostName(), callback);
}
/// @brief On Service Removed
void Discover::OnServiceRemoved(KDNSSD::RemoteService::Ptr service) {
// get the name of the device & lambda callback
const auto myDevice = QString::fromStdString(constants::getMDnsServiceName());
const auto callback = [&, service](const QHostInfo& info) {
if (info.error() != QHostInfo::NoError || info.addresses().isEmpty()) {
emit this->OnErrorOccurred(LOG("Unable to resolve service"));
return;
}
auto host = info.addresses().first();
auto port = quint16(service->port());
this->onServerRemoved({host, port});
};
// resolve the service
if (!service->resolve()) {
emit this->OnErrorOccurred(LOG("Unable to resolve service"));
return;
}
// check if the service is mine
if (service->serviceName() == myDevice) {
return;
}
// lookup the host
QHostInfo::lookupHost(service->hostName(), callback);
}
/**
* @brief Starts the discovery client by sending the
* broadcast message
*
* @param interval Interval between each broadcast
*/
void Discover::startDiscovery() {
// connect the browser signal to the slot of this class
const auto signal_r = &KDNSSD::ServiceBrowser::serviceRemoved;
const auto slot_r = &Discover::OnServiceRemoved;
connect(this->m_browser, signal_r, this, slot_r);
// connect the browser signal to the slot of this class
const auto signal_a = &KDNSSD::ServiceBrowser::serviceAdded;
const auto slot_a = &Discover::OnServiceFound;
connect(this->m_browser, signal_a, this, slot_a);
// start the browser
this->m_browser->startBrowse();
}
Edit:
A Reproducible Example would be following
#include <KDNSSD/PublicService>
#include <QCoreApplication>
#include <iostream>
int main(int argc, char **argv) {
QCoreApplication app(argc, argv);
KDNSSD::PublicService *service = new KDNSSD::PublicService("My files", "_http._tcp", 80);
std::cout << "Service: " << service->serviceName().toStdString() << std::endl;
bool isOK = service->publish();
std::cout << "Published: " << isOK << std::endl;
return app.exec();
}
When you build in Release mode the publish will be stuck but in debug mode, it will print as published 1. Also, I have created the issue In the Respository Thanks :)