zoukankan      html  css  js  c++  java
  • 关于(void**)及其相关的理解

    • #define LOADBASSFUNCTION (f) *((void **)&f)=( void*)GetProcAddress (hBass,# f)

    这一句话使用*((void**)&f)的原因在于,转化目标为左值(即转化f为void*类型(*)的函数指针)。
    注意这里的(void**)强制类型转换仅仅只是重新声明了指针解引用的方式,并没有提升指针的引用层级。意思上*((void**)&f)与f是相等的(忽略(void**)只看*&f就知道这本质上就是先取地址再解引用)。但是不能直接使用f,因为一个函数名不能做左值(要做左值必须指针化,也就是变成函数指针)。如果需要一个函数名直接做左值的话,需要将其转换为指针再取内容。实际上(void**)可以被看成(void*  *),后面的*表示函数被取地址后是一个指针,前面的void*表示这个指针被从新解释成了指向void*类型的指针(也就是相当于函数名被转换成了一个指针),之后对这个地址(&f)解引用,得到的自然就已经是一个函数指针了。

    在hge中有这样一行代码:

    • #define LOADBASSFUNCTION(f) *((void**)&f)=(void*)GetProcAddress(hBass,#f)

    这是一个宏,作用是将任意函数指针f,都赋值成来自动态链接库的同名函数。右边使用的是(void*)指针做强制类型转换,这是一个通用的方法,不用担心具体函数签名是什么。

    另外,只能使用函数指针来接收一个函数地址,无论是从动态库导出的函数。还是其他的函数。


    注释:

    (*)在c++中void*可以接收所有类型的指针,但是反之不可。在c中void*既可以赋值给任何指针,也可以被任何指针赋值。

  • 相关阅读:
    QT 创建一个线程播放监控视频
    C++基础(静态数据成员和静态成员函数)
    SDK的使用步骤
    QT加载自带字体
    QT release版QAudioDeviceInfo获取不到音频设备,而debug版可以获取到
    通过vs2015给QT添加模块
    pycharm修改字体与主题
    日志学习(二)——日志处理封装
    日志学习(一)
    配置文件学习(二)--写入配置文件
  • 原文地址:https://www.cnblogs.com/wubugui/p/3591304.html
Copyright © 2011-2022 走看看