martes, 1 de abril de 2025

no matching function for call to connect

Conectar un signal a un slot en Qt es tan simple como

connect(source,  &Source::Mysignal, destination, &Destination::slot);

Pero hoy recibi este error: No matching function for call to ‘MyClass::connect(QBluetoothDeviceDiscoveryAgent*&, , MyClass*, void (MyClass::*)(QBluetoothDeviceDiscoveryAgent::Error))’ 

En este caso el error es porque QBluetoothDeviceDiscoveryAgent tiene 2 miembros con el nombre "error", 

  • void QBluetoothDeviceDiscoveryAgent::error(QBluetoothDeviceDiscoveryAgent::Error error);
  • Error QBluetoothDeviceDiscoveryAgent::error() const;
Para desambiguar la llamada hay que usar un cast especificando la firma de tipado de la función
connect(discoveryAgent,
static_cast<void(QBluetoothDeviceDiscoveryAgent::*)(QBluetoothDeviceDiscoveryAgent::Error)>(&QBluetoothDeviceDiscoveryAgent::error),
this, &BlufiDeviceScanner::handleError);
view raw deambiguate.cpp hosted with ❤ by GitHub

undefined reference to vtable for MyClass

 Normalmente cuando el compilador reporta el error "undefined reference to vtable for MyClass" es porque

  • Una funcion miembro sobrecargada no se marco como "virtual"
  • La funcion miembro sobrecargada no esta definida( no se ha implementado el cuerpo de la funcion)
Pero hoy encontre un caso diferente, mientras creaba una clase derivada de QObject para un servicio que usa QtBluetooth, ambos casos estaban cubiertos. El problema resulto ser que no estaba activo el MOC (Meta Object Compiler).
Para Arreglarlo solo hay que activarlo con una variable en el archivo 
CMakelists.txt


cmake_minimum_required(VERSION 3.30)
project(bleservice)
set(CMAKE_AUTOMOC ON)
view raw CMakelists.txt hosted with ❤ by GitHub

Debe ir antes del comando "add_executable"

martes, 18 de febrero de 2025

Error 15 (Lookup error.) en libmosquittopp

        He estado programando un app para monitorear una flotilla usando MQTT. Todo iba muy bien estaba programando en ubuntu 24 LTS y Qt Creator, pero a la hora de querer probarla en windows no se conectaba al broker, esto era muy raro ya que en Linux estaba funcionando perfectamente.

        Depurando encontre que mosqpp::mosquittopp::connect_async estaba retornando 15, un "Lookup error", en vez de cero que seria lo optimo, estuve googleando y no encontraba ningun caso igual, probe montones de cosas, como por ejemplo:

  • Compilar diferente version de mosquitto
  • Usar la distribucion binaria
  • Conectar a otros brokers
  • Usar la ip publica del broker directamente
  • Cambiar el DNS de windows
  • Cambiar la configuracion de red de Windows
        Despues empece a leer el codigo fuente de mosquitto y vi que el codigo de error MOSQ_ERR_EAI (15) era retornado mucho despues de fallar una llamada a getaddrinfo() entonces decidi poner una llamada a  getaddrinfo() para saber de que se trataba. 
#include "ws2tcpip.h"
int main() {
addrinfo hints = {}, *res;
hints.ai_family = AF_INET;
int status = getaddrinfo("test.mosquitto.org", nullptr, &hints, &res);
if (status != 0) {
std::cerr << "getaddrinfo failed: " << gai_strerror(status) << std::endl;
} else {
std::cout << "getaddrinfo succeeded" << std::endl;
}
return 0;
}
view raw chkaddrinfo.cpp hosted with ❤ by GitHub
        La invocacion de la funcion fallo pero dio un mensaje de error interesante: "Either the application has not called WSAStartup, or WSAStartup failed."
        Ya con esa informacion sospeche de la solucion correcta: algo no estaba inicializado y asi era hacia falta llamar mosqpp::lib_init(), asi que agregue al inicio del programa:

mosqpp::lib_init();
atexit([](){mosqpp::lib_cleanup();});