I try to develop a Qt GUI application which will communicate with a board using USB. The library I use is libusb-win32 v1.2.5.0.
When I compile the application, the following errors occur:
./debug/thread_usb_comm.o: In function `ZN15thread_usb_comm15find_usb_deviceEtt':
thread_usb_comm.cpp:15: undefined reference to 'usb_find_busses'
thread_usb_comm.cpp:16: undefined reference to 'usb_find_devices'
thread_usb_comm.cpp:18: undefined reference to 'usb_get_busses'
thread_usb_comm.cpp:26: undefined reference to 'usb_open'
collect2: ld returned 1 exit status
mingw32-make[1]: [debug/CALSYS11_calib_app.exe] Error 1
mingw32-make: [debug] Error 2
The application code is:
(header file)
#ifndef THREAD_USB_COMM_H
#define THREAD_USB_COMM_H
#include <QThread>
#include <QtDebug>
#include "CALSYS11.h"
#include <lusb0_usb.h>
class thread_usb_comm : public QThread
{
Q_OBJECT
public:
thread_usb_comm();
private:
bool device_connected;
usb_dev_handle *p_usb_device;
bool find_usb_device(
unsigned short vendor_id,
unsigned short product_id
);
};
#endif // THREAD_USB_COMM_H
(source file)
#include "thread_usb_comm.h"
thread_usb_comm::thread_usb_comm()
{
device_connected = false;
}
bool thread_usb_comm::find_usb_device(
unsigned short vendor_id,
unsigned short product_id
)
{
struct usb_bus *bus;
struct usb_device *dev;
usb_find_busses();
usb_find_devices();
for (bus = usb_get_busses(); bus; bus = bus->next)
{
for (dev = bus->devices; dev; dev = dev->next)
{
if ((dev->descriptor.idVendor == vendor_id) &&
(dev->descriptor.idProduct == product_id))
{
qDebug ("Device found");
p_usb_device = usb_open(dev);
if (0 == p_usb_device)
{
qCritical ("Could not open USB device");
return false;
}
device_connected = true;
return true;
}
}
}
qDebug ("Cannot find specified device");
return false;
}
I added the link to the libusb library in the .pro file:
LIBS += -L\path\to\libusb-win32\lib\gcc -lusb
I develop on Windows 7.
Thank you,
Johann
Try to build release instead of debug or the static library is incompatible with compiler version (I faced same issue when I tried to build old static library with MinGW 4.4)
Related
I am try to get list of SSID in Fedora 31 Linux, by D-Bus message, using Qt5.
I am checking many tutorials, but still cant communicate by D-Bus, and I still do not understand differences between interface, path and service. With documentation help (https://developer.gnome.org/NetworkManager/stable/spec.html) and Internet I wrote:
QDBusInterface nm("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.NetworkManager.Device.Wireless", QDBusConnection::systemBus());
if(nm.isValid()) {
QDBusMessage msg = nm.call("GetAllAccessPoints");
}
But variable "msg" receiving one argument:
"No interface „org.freedesktop.NetworkManager.Device.Wireless” in object at path /org/freedesktop/NetworkManager"
How can I connect to D-Bus ?
Your confusion is justified, as the process is not really intuitive. Basically what you need to do is to first create a QDBusInterface representing NetworkManager itself. Via that object you need to get the list of the network interfaces, iterate through them, filter out the WiFi interface(s), creating a corresponding QDBusInterface, instruct the interface to scan the available networks, and then request the list of visible access points. Then you get the SSID property of each Access Point object. Here is a simple example which demonstrates the process with plain Qt:
list_ssid.pro:
QT -= gui
QT += dbus
SOURCES += list_ssid.cpp
list_ssid.cpp:
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtCore/QStringList>
#include <QtDBus/QtDBus>
#include <QDebug>
#include <QThread>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
// get the interface to nm
QDBusInterface nm("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager",
"org.freedesktop.NetworkManager", QDBusConnection::systemBus());
if(!nm.isValid())
{
qFatal("Failed to connect to the system bus");
}
// get all devices
QDBusMessage msg = nm.call("GetDevices");
qDebug() << "GetDevices reply: " << msg << endl;
QDBusArgument arg = msg.arguments().at(0).value<QDBusArgument>();
if(arg.currentType() != QDBusArgument::ArrayType)
{
qFatal("Something went wrong with getting the device list");
}
QList<QDBusObjectPath> pathsLst = qdbus_cast<QList<QDBusObjectPath> >(arg);
foreach(QDBusObjectPath p, pathsLst)
{
qDebug() << "DEV PATH: " << p.path();
// creating an interface used to gather this devices properties
QDBusInterface device("org.freedesktop.NetworkManager", p.path(),
"org.freedesktop.NetworkManager.Device", QDBusConnection::systemBus());
// 2 is WiFi dev, see https://people.freedesktop.org/~lkundrak/nm-docs/nm-dbus-types.html#NMDeviceType
if (device.property("DeviceType").toInt() != 2)
{
continue;
}
// we got a wifi device, let's get an according dbus interface
QDBusInterface wifi_device("org.freedesktop.NetworkManager", p.path(),
"org.freedesktop.NetworkManager.Device.Wireless", QDBusConnection::systemBus());
// we need to call scan on the inteface prior to request the list of interfaces
QMap<QString, QVariant> argList;
QDBusMessage msg = wifi_device.call("RequestScan", argList);
QThread::sleep(2); // not the best solution, but here we just wait for the scan
// doing the actual call
msg = wifi_device.call("GetAllAccessPoints");
qDebug()<< "Answer for GetAllAccessPoints: " << msg << endl << endl;
// dig out the paths of the Access Point objects:
QDBusArgument ap_list_arg = msg.arguments().at(0).value<QDBusArgument>();
QList<QDBusObjectPath> ap_path_list = qdbus_cast<QList<QDBusObjectPath> >(ap_list_arg);
// and iterate through the list
foreach(QDBusObjectPath p ,ap_path_list)
{
// for each Access Point we create an interface
QDBusInterface ap_interface("org.freedesktop.NetworkManager", p.path(),
"org.freedesktop.NetworkManager.AccessPoint", QDBusConnection::systemBus());
// and getting the name of the SSID
qDebug() << "SSID: " << ap_interface.property("Ssid").toString();
}
}
return 0;
}
The same using networkmanager-qt, for the sake of comparison:
CMakeLists.txt:
project(ssid_list LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt5 REQUIRED COMPONENTS
Core
Gui
Network
DBus
)
find_package(KF5NetworkManagerQt REQUIRED)
add_executable(ssid_list
ssid_list.cpp
)
target_link_libraries(ssid_list Qt5::Core Qt5::DBus Qt5::Network KF5::NetworkManagerQt)
ssid_list.cpp
#include <arpa/inet.h>
#include <QThread>
#include <NetworkManagerQt/Manager>
#include <NetworkManagerQt/Device>
#include <NetworkManagerQt/WirelessDevice>
#include <NetworkManagerQt/AccessPoint>
int main()
{
// getting all of the devices, and iterate through them
NetworkManager::Device::List list = NetworkManager::networkInterfaces();
Q_FOREACH (NetworkManager::Device::Ptr dev, list)
{
if(dev->type() != NM_DEVICE_TYPE_WIFI)
{
//skipping non-wifi interfaces
continue;
}
// creating a Wifi device with this object path
NetworkManager::WirelessDevice wifi_dev(dev->uni());
wifi_dev.requestScan();
QThread::sleep(2); // still not the best solution:w
//get the Object Path of all the visible access points
// and iterate through
foreach(QString ap_path, wifi_dev.accessPoints())
{
// creating an AccessPoint object with this path
NetworkManager::AccessPoint ap(ap_path);
// and finally get the SSID
qDebug() << "SSID:" << ap.ssid();
}
}
}
I am trying to use a semaphore of the arduino core for ESP32. My code is a follows:
#include <Arduino.h>
#include <freertos/task.h>
#include <freertos/queue.h>
#define configUSE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
void vTaskExample(void *pvParameters);
void accessSharedResource{}
volatile SemaphoreHandle_t xResourceSemaphore = NULL;
void setup()
{
xTaskCreatePinnedToCore(&vTaskExample, "example task", 1024, NULL, 2, NULL, 1);
}
void loop()
{
// Do nothing
}
void vTaskExample(void *pvParameters)
{
vSemaphoreCreateBinary(xResourceSemaphore);
while (true)
{
if (xSemaphoreAltTake(xResourceSemaphore, (TickType_t)0))
{
accessSharedResource();
xSemaphoreAltGive(xResourceSemaphore);
}
}
}
Unfortunately, during compilation (in the linking phase to be exact), I get the following error message:
main.cpp:(.text._Z12vTaskExamplePv+0x37): undefined reference to `xQueueAltGenericReceive'
main.cpp:(.text._Z12vTaskExamplePv+0x4b): undefined reference to `xQueueAltGenericSend'
I have looked up the freeRTOS documentation, and it indicates that the two functions are located in the queue.h; thus, should be available. Also, I have set the necessary freeRTOS configuration by setting configUSE_MUTEXES and configUSE_COUNTING_SEMAPHORES flags
Any suggestions why this does not compile?
Only prototypes are provided in queue.h - nothing executable. If you look at the FreeRTOS documentation you will note that the alternative API has been deprecated for a long time, and is only included in the build if configUSE_ALTERNATIVE_API is set to 1.
I am trying to create pointer objects for my defined class 'FeralScene'
But i keep getting this error "Syntax error: missing ';' before '*'"
i dont know wats wrong with my code... could smone pls help me out?
/***********************************************************************
2D Engine Header File
File Name: FeralFramework
File Desc: Header to the Main Framework file
************************************************************************/
#ifndef FERALFRAMEWORK_H
#define FERALFRAMEWORK_H
#pragma once
#include<Windows.h>
#include<d3d9.h>
#include<d3dx9.h>
#include<string>
#include <dinput.h>
#include"FeralScene.h"
#include"GraphicDevice.h"
#include "Stdinc.h"
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
class FeralFramework
{
public:
LPDIRECTINPUT8 inputDevice;
LPDIRECT3DDEVICE9 Device;
HWND WindowHandler;
HINSTANCE Instance;
FeralScene *CurrentScene,*PrevScene; // error occurs here
GraphicDevice graphicDevice;
static HWND StaticWindowHandle;
static IDirect3DDevice9 *GraphDevice;
int ScreenHeight;
int ScreenWidth;
bool IsFullScreen;
bool WindowCreation();
bool InitDirectx();
void MessageLoop();
void SetLighting();
void UpdateDrawLoopCallFunction();
void InitFrameWork();
void Render();
void initializeDirectInput();
//void Camera(int mx, int my);
void SceneSwitcher(FeralScene *SCENETOSWITCHTO);
// the FeralScene identifier error occurs here
FeralFramework();
FeralFramework(HINSTANCE Instance,int ScreenHeight,int ScreenWidth ,bool IsFullScreen,FeralScene *SentSceneObject );
// the FeralScene identifier error occurs here
FeralFramework(HINSTANCE Instance,FeralScene *SentSceneObject);
// the FeralScene identifier error occurs here
};
inline LRESULT CALLBACK WndProc(HWND WindowHandler,UINT Msg,WPARAM wparam,LPARAM lparam)
{
switch(Msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return true;
default:
return DefWindowProc(WindowHandler,Msg,wparam,lparam);
}
}
#endif
And here is a list of the errors that pop up when i try to compile it
1>c:\users\sys\documents\visual studio 2010\projects\feralengine\feralengine\feralframework.h(33): error C2143: syntax error : missing ';' before '*'
1>c:\users\sys\documents\visual studio 2010\projects\feralengine\feralengine\feralframework.h(33): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\sys\documents\visual studio 2010\projects\feralengine\feralengine\feralframework.h(33): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\sys\documents\visual studio 2010\projects\feralengine\feralengine\feralframework.h(33): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\sys\documents\visual studio 2010\projects\feralengine\feralengine\feralframework.h(55): error C2061: syntax error : identifier 'FeralScene'
1>c:\users\sys\documents\visual studio 2010\projects\feralengine\feralengine\feralframework.h(58): error C2061: syntax error : identifier 'FeralScene'
1>c:\users\sys\documents\visual studio 2010\projects\feralengine\feralengine\feralframework.h(59): error C2061: syntax error : identifier 'FeralScene'
What am i missing ? Any help will be appreciated :(
And here is the code for FeralScene
/***********************************************************************
2D Engine Header File
File Name: FeralScene
File Desc: Header to the FeralScene file
************************************************************************/
#pragma once
#include<d3dx9.h>
#pragma once
#include<Windows.h>
#include<d3d9.h>
#include<d3dx9.h>
#include"GraphicDevice.h"
#include "FeralFramework.h"
//#include "Vector.h"
class FeralScene
{
public:
HWND WindowHandler;
IDirect3DDevice9 *Device;
int BackBufferHeight;
int BackBufferWidth;
bool IsFullScreen,HasLoadedResources,HasUnloadedResources;
virtual void Initialize(FeralScene *SentSceneObject) =0;
virtual void Load(GraphicDevice graphicDevice) =0;
virtual void Update(GraphicDevice graphicDevice) =0;
virtual void Draw(GraphicDevice graphicDevice) =0;
virtual void Unload() =0;
virtual void Lighting()=0;
virtual void LoadAnim()=0;
virtual void UnloadAnim()=0;
};
You are including FeralFrameWork.h in feralscene.h. Which doesnt know of FeralScene.h yet. You can crete a forward decleration in FeralFramework.h. Also I suggest using proper macros in FeralScene.h also to avoid multiple decelerations.
Since you are using pointer types in header forward decleration will resolve the issue.
// this should be before the class FeralFramework
class FeralScene;
#include <QtCore/QCoreApplication>
#include <QTCore>
#include <QtNetwork>
#include <QDebug>
#define CONNECT(sndr, sig, rcvr, slt) connect(sndr, SIGNAL(sig), rcvr, SLOT(slt))
class mynet : QObject
{
Q_OBJECT
public:
mynet()
{}
void start()
{
CONNECT(tcpServer, newConnection(), this, acceptConnection());
CONNECT(tcpClient, connected(), this, startTransfer());
CONNECT(tcpClient, bytesWritten(qint64), this, updateClientProgress(qint64));
CONNECT(tcpClient, error(QAbstractSocket::SocketError), this, displayError(QAbstractSocket::SocketError));
// start server listening
tcpServer->listen();
while(!tcpServer->isListening());
// make client connection
tcpClient->connectToHost(QHostAddress::LocalHost, tcpServer->serverPort());
}
public slots:
void acceptConnection()
{
tcpServerConnection = tcpServer->nextPendingConnection();
CONNECT(tcpServerConnection, readyRead(), this, updateServerProgress());
CONNECT(tcpServerConnection, error(QAbstractSocket::SocketError), this, displayError(QAbstractSocket));
tcpServer->close();
}
void startTransfer()
{
bytesToWrite = TotalBytes - (int)tcpClient->write(QByteArray(PayloadSize, '#'));
}
void updateServerProgress()
{
bytesReceived += (int)tcpServerConnection->bytesAvailable();
tcpServerConnection->readAll();
if (bytesReceived == TotalBytes)
{
qDebug() << "done";
tcpServerConnection->close();
}
}
void updateClientProgress(qint64 numBytes)
{
// callen when the TCP client has written some bytes
bytesWritten += (int)numBytes;
// only write more if not finished and when the Qt write buffer is below a certain size.
if (bytesToWrite > 0 && tcpClient->bytesToWrite() <= 4*PayloadSize)
bytesToWrite -= (int)tcpClient->write(QByteArray(qMin(bytesToWrite, PayloadSize), '#'));
}
void displayError(QAbstractSocket::SocketError socketError)
{
if (socketError == QTcpSocket::RemoteHostClosedError)
return;
qDebug() << tcpClient->errorString();
tcpClient->close();
tcpServer->close();
}
private:
QTcpServer* tcpServer;
QTcpSocket* tcpClient;
QTcpSocket* tcpServerConnection;
int bytesToWrite;
int bytesWritten;
int bytesReceived;
int TotalBytes;
int PayloadSize;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
mynet m1;
m1.start();
return a.exec();
}
I get an
Undefined symbols for architecture x86_64:
"vtable for mynet", referenced from:
mynet::mynet() in main.o
mynet::~mynet()in main.o.
Please advise what I am doing wrong. Can I not inline the method definitions in the class for some reason in Qt?
You need to add your class to the .pro file
HEADERS += mynet.h
SOURCES += mynet.cpp
so the meta-object compiler can scan them and work out they need moc'ing and generate the relevant stubs.
Assuming that your source file is named foo.cpp, you have to put the following line at the very end:
#include "foo.moc"
This line tells qmake and the VS Qt add-in that the file should be run via moc, and that the generated moc file should be named foo.moc.
You also have problems in the #include lines for Qt headers. I've found that the following work:
#include <QtCore/QCoreApplication>
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket>
Make sure to add network to your .pro file. This will create the correct linking to the network library functions.
QT += core network
Two things:
1) You should publicly derive from QObject.
2) Are you moc'ing this file and then compiling and linking the output? If you include the Q_OBJECT macro and don't moc, you will get an error like that.
I want add support for playback of mp3 file in my Qt app for embedded linux.
I'm not able to use phonon in Qt. After adding QT += phonon in .pro file it gives me the following error during compilation :
/usr/lib/gcc/i486-linux-gnu/4.4.1/../../../../lib/libphonon.so: undefined reference to `QWidget::x11Event(_XEvent*)'
/usr/lib/gcc/i486-linux-gnu/4.4.1/../../../../lib/libphonon.so: undefined reference to `QDataStream::QDataStream(QByteArray*, int)'
collect2: ld returned 1 exit status
So now i'm thinking of using the mpg123 lib for decoding mp3 files.
I need help integrating the library in Qt. I've never used a pure c++ library in Qt before so i don't have much idea on how to integrate it.
Hey all !! Finally I figured it out !!
int MP3Player::Init(const char *pFileName)
{
mpg123_init();
m_mpgHandle = mpg123_new(0, 0);
if(mpg123_open(m_mpgHandle, pFileName) != MPG123_OK)
{
qFatal("Cannot open %s: %s", pFileName, mpg123_strerror(m_mpgHandle));
return 0;
}
}
int MP3Player::Play()
{
unsigned char *audio;
int mc;
size_t bytes;
qWarning("play_frame");
static unsigned char* arr = 0;
/* The first call will not decode anything but return MPG123_NEW_FORMAT! */
mc = mpg123_decode_frame(m_mpgHandle, &m_framenum, &audio, &bytes);
if(bytes)
{
/* Normal flushing of data, includes buffer decoding. */
/*This function is my already implemented audio class which uses ALSA to output decoded audio to Sound Card*/
if (m_audioPlayer.Play(arr,bytes) < (int)bytes)
{
qFatal("Deep trouble! Cannot flush to my output anymore!");
}
}
/* Special actions and errors. */
if(mc != MPG123_OK)
{
if(mc == MPG123_ERR)
{
qFatal("...in decoding next frame: %s", mpg123_strerror(m_mpgHandle));
return CSoundDecoder::EOFStream;
}
if(mc == MPG123_DONE)
{
return CSoundDecoder::EOFStream;
}
if(mc == MPG123_NO_SPACE)
{
qFatal("I have not enough output space? I didn't plan for this.");
return CSoundDecoder::EOFStream;
}
if(mc == MPG123_NEW_FORMAT)
{
long iFrameRate;
int encoding;
mpg123_getformat(m_mpgHandle, &iFrameRate, &m_iChannels, &encoding);
m_iBytesPerChannel = mpg123_encsize(encoding);
if (m_iBytesPerChannel == 0)
qFatal("bytes per channel is 0 !!");
m_audioPlayer.Init(m_iChannels , iFrameRate , m_iBytesPerChannel);
}
}
}
In order to get mpg123 working with your QT project you try following steps:
1.download and install mpg123: from the folder where you extracted it to (e.g /home/mpg123-1.13.0/) run ./configure and then "sudo make install"
2.if there are no errors put this line to your *.pro file
LIBS += /usr/local/lib/libmpg123.so
3.then code below should run fine for you:
#include "mpg123.h"
#include <QDebug>
void MainWindow::on_pushButton_2_clicked()
{
const char **decoders = mpg123_decoders();
while (*decoders != NULL)
{
qDebug() << *decoders;
decoders++;
}
}
alternatively you can call mpg123 via system call:
system("mpg123 /home/test.mp3");
hope this helps, regards