• 关于不完全类型的认识


    最近在使用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的方式访问结构体成员的,整个结构体对于用户来说就是一个黑匣子。

  • 相关阅读:
    wordpress图片压缩插件-免费批量wordpress图片压缩
    C#:实现分枝绑定背包求解器算法(附完整源码)
    巧用@Conditional注解根据配置文件注入不同的bean对象
    使用JMeter进行接口压力测试
    Mysql 表的约束
    MySQL知识总结 (六) MySQL调优
    记录wisemodel上传失败
    【观察】OpenHarmony:技术先进“创新局”,持续创新“谋新篇”
    【iOS自动化测试】第二章:环境安装
    浅谈继承之默认成员函数
  • 原文地址:https://www.cnblogs.com/style--moon/p/16420992.html