簡體   English   中英

錯誤:無效使用非靜態成員函數'int test :: hotplug_callback(libusb_context *,libusb_device *,libusb_hotplug_event,void *)'

[英]error: invalid use of non-static member function ‘int test::hotplug_callback(libusb_context*, libusb_device*, libusb_hotplug_event, void*)’

我改編了libusb hotplug示例

* libusb example program for hotplug API * Copyright © 2012-2013 Nathan Hjelm <hjelmn@mac.com>

(下面的代碼)作為測試,並將其放在類中,因為我的真實程序存在相同的問題。 我知道,如果我將static放在兩個回調函數的前面,它會起作用,但我不希望它們是靜態的。 我想從回調訪問我的實例變量。 這個想法是用戶插入一個USB設備,我們稱其為usbXYZ。 從回調中,我實例化了類usbXYZ並放入了std :: map-用戶將其刪除,然后從地圖中將其刪除。 包含std :: map及其對象的類具有寫入設備的“更高級別”方法。

我如何使回調函數不靜態地工作? 如果可能的話,請解釋一下,因為我不理解。 謝謝。

#include <stdlib.h>
#include <stdio.h>
#include <thread>

#include "libusb-1.0/libusb.h"

class test{
public:
    test() {
        okGo();
    }

private:
    int done = 0;
    libusb_device_handle *handle = NULL;

    int LIBUSB_CALL hotplug_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
    {
        struct libusb_device_descriptor desc;
        int rc;

        (void)ctx;
        (void)dev;
        (void)event;
        (void)user_data;

        rc = libusb_get_device_descriptor(dev, &desc);
        if (LIBUSB_SUCCESS != rc) {
            fprintf (stderr, "Error getting device descriptor\n");
        }

        printf ("Device attached: %04x:%04x\n", desc.idVendor, desc.idProduct);

        if (handle) {
            libusb_close (handle);
            handle = NULL;
        }

        rc = libusb_open (dev, &handle);
        if (LIBUSB_SUCCESS != rc) {
            fprintf (stderr, "Error opening device\n");
        }

        done++;

        return 0;
    }

    int LIBUSB_CALL hotplug_callback_detach(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
    {
        (void)ctx;
        (void)dev;
        (void)event;
        (void)user_data;

        printf ("Device detached\n");

        if (handle) {
            libusb_close (handle);
            handle = NULL;
        }

        done++;

        return 0;
    }

    int okGo(){
        libusb_hotplug_callback_handle hp[2];
        int product_id, vendor_id, class_id;
        int rc;

        vendor_id  = LIBUSB_HOTPLUG_MATCH_ANY;
        product_id = LIBUSB_HOTPLUG_MATCH_ANY;
        class_id   = LIBUSB_HOTPLUG_MATCH_ANY;

        rc = libusb_init (NULL);
        if (rc < 0)
        {
            printf("failed to initialise libusb: %s\n", libusb_error_name(rc));
            return EXIT_FAILURE;
        }

        if (!libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)) {
            printf ("Hotplug capabilites are not supported on this platform\n");
            libusb_exit (NULL);
            return EXIT_FAILURE;
        }

        rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, LIBUSB_HOTPLUG_ENUMERATE, vendor_id,
                                               product_id, class_id, hotplug_callback, NULL, &hp[0]);
        if (LIBUSB_SUCCESS != rc) {
            fprintf (stderr, "Error registering callback 0\n");
            libusb_exit (NULL);
            return EXIT_FAILURE;
        }

        rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, LIBUSB_HOTPLUG_ENUMERATE, vendor_id,
                                               product_id,class_id, hotplug_callback_detach, NULL, &hp[1]);
        if (LIBUSB_SUCCESS != rc) {
            fprintf (stderr, "Error registering callback 1\n");
            libusb_exit (NULL);
            return EXIT_FAILURE;
        }

        while (done < 20) {
            //rc = libusb_handle_events (NULL);
            if (libusb_handle_events_completed(nullptr, nullptr) != LIBUSB_SUCCESS)
                printf("libusb_handle_events() failed: %s\n", libusb_error_name(rc));
        }

        if (handle) {
            libusb_close (handle);
        }

        libusb_exit (NULL);

        return EXIT_SUCCESS;
    }
};


int main(int argc, char *argv[])
{
    std::unique_ptr<test> testClass1 = std::make_unique<test>();

    //just test
    for (;;)
    {
        //main service loop
        std::this_thread::sleep_for(std::chrono::microseconds(2000000));
    }
}

libusb是一個C庫,它只能使用非成員函數指針。 非成員函數(或static成員函數)指針與指向非靜態成員函數的指針之間的區別在於,非靜態成員函數需要調用一個對象 ,而C不了解C ++ “對象”。

使用libusb,您可以使用static成員函數和用戶數據指針(現在您傳遞空指針)來解決它。

例如

class test
{
    // ...

    static int LIBUSB_CALL static_hotplug_callback_detach(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
    {
        return reinterpret_cast<test*>(user_data)->hotplug_callback_detach(ctx, dev, event);
    }

    int hotplug_callback_detach(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event)
    {
        // Current code
    }

    // ...

    int okGo()
    {
        // ...

        rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, LIBUSB_HOTPLUG_ENUMERATE, vendor_id,
                                           product_id,class_id, static_hotplug_callback_detach, this, &hp[1]);

        // ...
    }

請注意,在注冊回調時會使用static成員函數,並且this函數將作為用戶數據指針傳遞。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM