Kdnssd Not working in Release Mode Qt c++

54 views Asked by At

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 :)

0

There are 0 answers