Russian Qt Forum
Ноябрь 07, 2024, 06:32 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Сторонняя подключенная библиотека не работает  (Прочитано 1329 раз)
Александра
Новичок

Offline Offline

Сообщений: 5


Просмотр профиля
« : Сентябрь 25, 2024, 12:53 »

Добрый день. Создаю проект, в котором нужно будет общаться с hid-устройством, чтобы контролировать зажигающиеся светодиоды. Сама я со сторонними библиотеками дело не имела, потому длительное изучение данной темы привело меня на небезызвестную (судя по ее упоминаниям) библиотеку hidapi с github'а. Саму библиотеку я скомпилировала, как было написано в README для WINDOWS на Visual studio, создала .dll, .lib файлы, стала подключать ее к проекту, который я пока не разбирала, но пример которого был взят с другого сайта, чтобы просто проверить хотя бы подключение библиотеки, не говоря уже о работе.
Подключала я ее следующим образом:
keykey.pro
Код:
QT -= gui
 
CONFIG += c++11 console
CONFIG -= app_bundle
 
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
 
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
 
SOURCES += \
        main.cpp
 
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
 
INCLUDEPATH += $$PWD/.
LIBS += -L$$PWD/./ -lhidapi

main.cpp
Код:
#include <QCoreApplication>
 
#include <stdio.h>
#include <wchar.h>
#include <string.h>
#include <stdlib.h>
#include "hidapi.h"
#include <unistd.h>
 
#define MAX_STR 255
 
int main(int argc, char *argv[])
{
    //QCoreApplication a(argc, argv);
    //return a.exec();
 
 
    int res;
    unsigned char buf[256];
 
    wchar_t wstr[MAX_STR];
    hid_device *handle;
    int i;
 
 
    struct hid_device_info *devs, *cur_dev;
 
    if (hid_init())
        return -1;
 
        devs = hid_enumerate(0x0, 0x0);
        cur_dev = devs;
        while (cur_dev) {
            printf("Device Found\n  type: %04hx %04hx\n  path: %s\n  serial_number: %ls", cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number);
            printf("\n");
            printf("  Manufacturer: %ls\n", cur_dev->manufacturer_string);
            printf("  Product:      %ls\n", cur_dev->product_string);
            printf("  Release:      %hx\n", cur_dev->release_number);
            printf("  Interface:    %d\n",  cur_dev->interface_number);
            printf("\n");
            cur_dev = cur_dev->next;
        }
        hid_free_enumeration(devs);
 
        // Set up the command buffer.
        memset(buf,0x00,sizeof(buf));
        buf[0] = 0x01;
        buf[1] = 0x81;
 
 
        // Open the device using the VID, PID,
        // and optionally the Serial number.
        ////handle = hid_open(0x4d8, 0x3f, L"12345");
        handle = hid_open(0x4d8, 0x3f, NULL);
        if (!handle) {
            printf("unable to open device\n");
            return 1;
        }
 
        // Read the Manufacturer String
        wstr[0] = 0x0000;
        res = hid_get_manufacturer_string(handle, wstr, MAX_STR);
        if (res < 0)
            printf("Unable to read manufacturer string\n");
        printf("Manufacturer String: %ls\n", wstr);
 
        // Read the Product String
        wstr[0] = 0x0000;
        res = hid_get_product_string(handle, wstr, MAX_STR);
        if (res < 0)
            printf("Unable to read product string\n");
        printf("Product String: %ls\n", wstr);
 
        // Read the Serial Number String
        wstr[0] = 0x0000;
        res = hid_get_serial_number_string(handle, wstr, MAX_STR);
        if (res < 0)
            printf("Unable to read serial number string\n");
        printf("Serial Number String: (%d) %ls", wstr[0], wstr);
        printf("\n");
 
        // Read Indexed String 1
        wstr[0] = 0x0000;
        res = hid_get_indexed_string(handle, 1, wstr, MAX_STR);
        if (res < 0)
            printf("Unable to read indexed string 1\n");
        printf("Indexed String 1: %ls\n", wstr);
 
        // Set the hid_read() function to be non-blocking.
        hid_set_nonblocking(handle, 1);
 
        // Try to read from the device. There shoud be no
        // data here, but execution should not block.
        res = hid_read(handle, buf, 17);
 
        // Send a Feature Report to the device
        buf[0] = 0x2;
        buf[1] = 0xa0;
        buf[2] = 0x0a;
        buf[3] = 0x00;
        buf[4] = 0x00;
        res = hid_send_feature_report(handle, buf, 17);
        if (res < 0) {
            printf("Unable to send a feature report.\n");
        }
 
        memset(buf,0,sizeof(buf));
 
        // Read a Feature Report from the device
        buf[0] = 0x2;
        res = hid_get_feature_report(handle, buf, sizeof(buf));
        if (res < 0) {
            printf("Unable to get a feature report.\n");
            printf("%ls", hid_error(handle));
        }
        else {
            // Print out the returned buffer.
            printf("Feature Report\n   ");
            for (i = 0; i < res; i++)
                printf("%02hhx ", buf[i]);
            printf("\n");
        }
 
        memset(buf,0,sizeof(buf));
 
        // Toggle LED (cmd 0x80). The first byte is the report number (0x1).
        buf[0] = 0x1;
        buf[1] = 0x80;
        res = hid_write(handle, buf, 17);
        if (res < 0) {
            printf("Unable to write()\n");
            printf("Error: %ls\n", hid_error(handle));
        }
 
 
        // Request state (cmd 0x81). The first byte is the report number (0x1).
        buf[0] = 0x1;
        buf[1] = 0x81;
        hid_write(handle, buf, 17);
        if (res < 0)
            printf("Unable to write() (2)\n");
 
        // Read requested state. hid_read() has been set to be
        // non-blocking by the call to hid_set_nonblocking() above.
        // This loop demonstrates the non-blocking nature of hid_read().
        res = 0;
        while (res == 0) {
            res = hid_read(handle, buf, sizeof(buf));
            if (res == 0)
                printf("waiting...\n");
            if (res < 0)
                printf("Unable to read()\n");
            usleep(500*1000);
        }
 
        printf("Data read:\n   ");
        // Print out the returned buffer.
        for (i = 0; i < res; i++)
            printf("%02hhx ", buf[i]);
        printf("\n");
 
        hid_close(handle);
 
        /* Free static HIDAPI objects. */
        hid_exit();
 
        return 0;
}

Но у меня везде, где упоминаются методы из библиотеки показывается сообщение такого вида: undefined reference to `hid_init'

Все файлы у меня находятся в одной папке и имеют следующий вид:
keykey:
| hidapi.dll
| hidapi.h
| hidapi.lib
| keykey.pro
| main.cpp

Помогите, пожалуйста, разобраться, в чем проблема. Я уже множество разных методов перепробовала: и указывать в либсе .dll, и указывать .lib, и располагать файлы в друих местах. Но что интересно, если я на F2 буду переходить по ссылкам относительно какой-то функции, то меня отправляет в файл "hidapi.h" без каких-то проблем.
Заранее извиняюсь за мое невежество: в интернете много новой и сложной для меня информации, поэтому могу жёстко "косячить"...
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 583


Просмотр профиля
« Ответ #1 : Сентябрь 26, 2024, 10:14 »

Эти ошибки возникают на этапе линковки и только в Windows, так как методы библиотеки не экспортированы.
Обычно в проектах делают что-то типа

Код
C++ (Qt)
#if defined( BUILD_DLL )
   #define IMPORT_EXPORT __declspec(dllexport)
#else
   #define IMPORT_EXPORT __declspec(dllimport)
#endif
class IMPORT_EXPORT MyClass {
   ...
};
 
IMPORT_EXPORT void myMethod();
 

Где при сборке библиотеки IMPORT_EXPORT определяется как __declspec(dllexport), а при сборке приложения как__declspec(dllimport).

Похоже hidapi не содержит такого механизма, либо при его сборке не определен необходимый DEFINE.

Можно обойтись без IMPORT_EXPORT, тогда необходимо сгенерировать def файл по инструкции

https://learn.microsoft.com/ru-ru/cpp/build/exporting-from-a-dll-using-def-files?view=msvc-170
https://learn.microsoft.com/en-us/cpp/build/reference/def-specify-module-definition-file?view=msvc-170
« Последнее редактирование: Сентябрь 26, 2024, 10:28 от ssoft » Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 583


Просмотр профиля
« Ответ #2 : Сентябрь 26, 2024, 13:06 »

Еще есть вариант собрать hidapi в виде статической библиотеки.
Тип указывается в настройках проекта в Visual Studio.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.213 секунд. Запросов: 22.