Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 错误:无效使用非静态成员函数‘;int test::热插拔回调(libusb_上下文*、libusb_设备*、libusb_热插拔事件、void*)和x2019;_C++_Libusb - Fatal编程技术网

C++ 错误:无效使用非静态成员函数‘;int test::热插拔回调(libusb_上下文*、libusb_设备*、libusb_热插拔事件、void*)和x2019;

C++ 错误:无效使用非静态成员函数‘;int test::热插拔回调(libusb_上下文*、libusb_设备*、libusb_热插拔事件、void*)和x2019;,c++,libusb,C++,Libusb,我将libusb热插拔示例改编自 热插拔API的libusb示例程序 *版权所有©2012-2013 Nathan Hjelm (下面的代码)作为一个测试,并把它放在一个类中,因为我的真实程序也有同样的问题。 我知道如果我把static放在两个回调的前面,它就会正常工作,但我不希望它们是静态的。我想从回调中访问实例变量。这个想法是用户插入一个usb设备,我们称之为usbXYZ。从回调中,我实例化类usbXYZ并放入一个std::map-user将其删除,我将其从映射中删除。包含std::map及

我将libusb热插拔示例改编自

热插拔API的libusb示例程序 *版权所有©2012-2013 Nathan Hjelm

(下面的代码)作为一个测试,并把它放在一个类中,因为我的真实程序也有同样的问题。 我知道如果我把static放在两个回调的前面,它就会正常工作,但我不希望它们是静态的。我想从回调中访问实例变量。这个想法是用户插入一个usb设备,我们称之为usbXYZ。从回调中,我实例化类usbXYZ并放入一个std::map-user将其删除,我将其从映射中删除。包含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-1.0/libusb.h”
课堂测试{
公众:
测试(){
okGo();
}
私人:
int done=0;
libusb_设备_handle*handle=NULL;
int LIBUSB_CALL hotplug_回调(LIBUSB_上下文*ctx,LIBUSB_设备*dev,LIBUSB_hotplug_事件,void*用户数据)
{
结构libusb_设备描述符desc;
int rc;
(无效)ctx;
(d)发展;
(无效)事件;
(作废)用户数据;
rc=libusb\u获取设备\u描述符(dev和desc);
if(libu_SUCCESS!=rc){
fprintf(stderr,“获取设备描述符时出错”);
}
printf(“连接的设备:%04x:%04x\n”,desc.idVendor,desc.idProduct);
if(句柄){
libu_关闭(手柄);
handle=NULL;
}
rc=libusb_打开(开发和句柄);
if(libu_SUCCESS!=rc){
fprintf(stderr,“打开设备时出错\n”);
}
完成++;
返回0;
}
int LIBUSB_CALL hotplug_callback_detach(LIBUSB_上下文*ctx,LIBUSB_设备*dev,LIBUSB_hotplug_事件,void*用户数据)
{
(无效)ctx;
(d)发展;
(无效)事件;
(作废)用户数据;
printf(“设备分离\n”);
if(句柄){
libu_关闭(手柄);
handle=NULL;
}
完成++;
返回0;
}
int okGo(){
libusb_热插拔_回调_处理hp[2];
int产品标识、供应商标识、类别标识;
int rc;
供应商id=LIBUSB\u热插拔\u匹配\u任意;
产品id=LIBUSB\u热插拔\u匹配\u任意;
class\u id=LIBUSB\u热插拔\u匹配\u任意;
rc=libusb_init(NULL);
if(rc<0)
{
printf(“未能初始化libusb:%s\n”,libusb_错误_名称(rc));
返回退出失败;
}
如果(!libusb_具有_功能(libusb_CAP_具有_热插拔)){
printf(“此平台不支持热插拔功能\n”);
libu_退出(空);
返回退出失败;
}
rc=libusb\u热插拔\u寄存器\u回调(空,libusb\u热插拔\u事件\u设备\u到达,libusb\u热插拔\u枚举,供应商\u id,
产品id、类id、热插拔回调、NULL和hp[0]);
if(libu_SUCCESS!=rc){
fprintf(stderr,“注册回调0时出错”);
libu_退出(空);
返回退出失败;
}
rc=libusb\u热插拔\u寄存器\u回调(NULL,libusb\u热插拔\u事件\u设备\u左侧,libusb\u热插拔\u枚举,供应商\u id,
产品id、类id、热插拔回调、空和hp[1]);
if(libu_SUCCESS!=rc){
fprintf(stderr,“注册回调1时出错”);
libu_退出(空);
返回退出失败;
}
而(完成时间<20){
//rc=libusb\u handle\u事件(空);
if(libusb\u handle\u events\u completed(nullptr,nullptr)!=libusb\u SUCCESS)
printf(“libusb_handle_events()失败:%s\n”,libusb_error_name(rc));
}
if(句柄){
libu_关闭(手柄);
}
libu_退出(空);
返回退出成功;
}
};
int main(int argc,char*argv[])
{
std::unique_ptr testClass1=std::make_unique();
//只是测试
对于(;;)
{
//主服务环路
std::this_thread::sleep_for(std::chrono::微秒(2000000));
}
}

libusb是一个C库,它只能接受非成员函数指针。非成员函数(或<代码> static < /COD>成员函数)指针和非静态成员函数的指针之间的区别是非静态成员函数需要调用对象,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 int LIBUSB_CALL static_hotplug_callback_detach(LIBUSB_上下文*ctx,LIBUSB_设备*dev,LIBUSB_hotplug_事件,void*用户数据)
{
返回reinterpret\u cast(用户数据)->热插拔\u回调\u分离(ctx、开发、事件);
}
int热插拔回调分离(libusb\u上下文*ctx,libusb\u设备*dev,libusb\u热插拔事件)
{
//现行代码
}
// ...
int okGo()
{
// ...
rc=libusb\u热插拔\u寄存器\u回调(NULL,libusb\u热插拔\u事件\u设备\u左侧,libusb\u热插拔\u枚举,供应商\u id,
产品标识、类标识、静态热插拔标识、回调标识、此标识和hp[1]);
// ...
}

请注意,注册回调时使用了
静态
成员函数,并且
作为用户数据指针传递。

libusb是一个C库,它只能接受非成员函数指针。非成员