• 关于不完全类型的认识


    最近在使用libusb做USB驱动,编写代码的时候发现了一段有趣的代码

    typedef struct libusb_device libusb_device;

    而这个结构体是没有定义的,在我做出如下定义时编译器会报错: error C2079: “dev”使用未定义的 struct“CMW7300ISPTOOLDlg::OnBnClickedButton1::libusb_devic”

    struct libusb_devic dev;

    而定义为struct libusb_devic* dev;则不会报错,这是为什么呢?

    网络搜索看到说这个属于不完全类型,typedef struct libusb_device libusb_device;这断代码相当于申明了一个结构体libusb_device,但是没有实际定义,类似于C语言的extern int A;在不使用申明的变量时,编译器是不会报错的,但是如果要使用的话,就需要先定义变量,比如要使用给A赋值2,就需要用int A = 2;直接使用A = 2编译器就会报错。同样的对于不完全定义的结构体typedef struct libusb_device libusb_device;而言也是一样的,不能直接定义struct libusb_devic dev;这样定义的话编译器不知道结构体的libusb_devic的大小,不知道开辟多少内存给变量,所以会报错,但是如果用struct libusb_devic* dev;就没问题了,因为这样定义的是一个指针,对于编译器而言,指针的大小是确定的(32位)4字节。

    这里又出现一个新问题,这样定义之后在使用这个结构体的时候还是需要先定义如下结构体:

    struct libusb_devic

    {

      若干变量;

    }

    那么这个不完全类型的意义何在呢?后来发现主要是封装时使用,当我们不希望别人访问和修改结构体内容的时候,我们就可以将结构体的定义封装成库,那么别人调用库的时候只能使用不完全类型作为接口,这样就没法访问结构体成员了,更不能修改结构体内容了。比如如下代码

    ssize_t LIBUSB_CALL libusb_get_device_list(libusb_context *ctx,
    libusb_device ***list);

    这就是libusb库中的一个函数,其参数libusb_device ***list是个封装在库里面的结构体,当我们要调用这个函数的时候,就需要先定义一个不完全变量struct libusb_device** device_list;,再调用函数libusb_get_device_list(NULL, &device_list);

    这是我们是无法通过device_list->menber的方式访问结构体成员的,整个结构体对于用户来说就是一个黑匣子。

  • 相关阅读:
    计算机找不到MSVCR120.dll,MSVCR120.dll丢失的三种解决方法
    SpringCloud-3-基础工程构建
    Centos7 安装 Nginx及启动命令
    2022年上半年软设算法题代码
    spring中的DI
    LeetCode 17 Java 实现
    Debezium系列之:采集数据库数据实现对表指定的字段进行加密,下游实现对表加密后的字段进行解密
    改变金融贷款市场营销方式 ---- 运营商大数据精准获客
    再写一遍的网络流
    批量插入,部分参数为null,报sql语法错误解决方案
  • 原文地址:https://www.cnblogs.com/style--moon/p/16420992.html