• 关于不完全类型的认识


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

  • 相关阅读:
    【跟小嘉学 Rust 编程】三十一、Rust的日志与追踪
    目前为止 DAO靠什么盈利?
    国内免费好用 Chat GPT推荐
    (二)基于kubernetes(1.25.2) 进行基础prometheus监控
    美联储加息步伐“暂停”!BTC凌晨力守27000美元!
    y127.第七章 服务网格与治理-Istio从入门到精通 -- EnvoyFilter(十三)
    笔记39:在Pycharm中为项目添加新解释器
    django农产品销售系统-计算机毕业设计源码65418
    C语言中各种运算符用法
    【云原生】k8s中volumeMounts.subPath的巧妙用法
  • 原文地址:https://www.cnblogs.com/style--moon/p/16420992.html