zoukankan      html  css  js  c++  java
  • [转]GCC系列: __attribute__((visibility("")))

    在 objc-api.h 里面有很多关于__attribute__ 的定义.

    例如

    #if !defined(OBJC_VISIBLE)
    #   if TARGET_OS_WIN32
    #       if defined(BUILDING_OBJC)
    #           define OBJC_VISIBLE __declspec(dllexport)
    #       else
    #           define OBJC_VISIBLE __declspec(dllimport)
    #       endif
    #   else
    #       define OBJC_VISIBLE  __attribute__((visibility("default")))
    #   endif
    #endif

    可以看到

    OBJC_VISIBLE 的定义方式是 __attribute__((visibility("default"))).

    那么究竟有什么作用呢? 下面举例说明.

    GCC 有个visibility属性, 该属性是说, 启用这个属性:

    1. 当-fvisibility=hidden时

    动态库中的函数默认是被隐藏的即 hidden. 除非显示声明为__attribute__((visibility("default"))).

    2. 当-fvisibility=default时

     动态库中的函数默认是可见的.除非显示声明为__attribute__((visibility("hidden"))).

    特别说明: 这个特性是 GCC4.0 以后才有的.

    基于GCC系列: 加载静态链接库的例子, 谈谈 visibility.

    Car.c

    #include<stdio.h>  
    #include<stdlib.h> 
     
    __attribute ((visibility("default"))) int drive()
    {
        printf("Car driving...
    ");
     
        return 0;
    }
     
    void stop()
    {
        printf("Car stop.
    ");
    }

    注意: attribute 的定义和使用方法.

    使用 visibility 属性来编译动态链接库.

    g++-4.9 -shared -o libCar.so -fvisibility=hidden Car.c

    这样一来, drive 方法是可见的, 但是 stop 是不可见的.

    main.c

    #include<stdio.h>  
    #include<stdlib.h> 
     
    //
    // 在 gcc 编译器下, 必须声明方法
    // 在 clang 编译下, 只是给了警告
    //
     
    int drive();
    void stop();
     
    int main()
    {
        drive();
        stop();
     
        return 0;
    }

    编译

    g++-4.9 -o app main.c -L ./ -lCar

    提示信息

    Undefined symbols for architecture x86_64:
      "stop()", referenced from:
          _main in ccZnwENu.o
    ld: symbol(s) not found for architecture x86_64
    collect2: error: ld returned 1 exit status

    这说明了上面提到的第一中情况.

    重新编译 Car.c, 换个方式

    g++-4.9 -shared -o libCar.so -fvisibility=default Car.c

    注意: 这次使用了 default 属性.

    编译 main.c

    g++-4.9 -o app main.c -L ./ -lCar

    编译成功, 运行 app

    ./app 
    Car driving...
    Car stop.


    那么修改一下 Car.c 的代码

    #include<stdio.h>  
    #include<stdlib.h> 
     
    __attribute ((visibility("default"))) int drive()
    {
        printf("Car driving...
    ");
     
        return 0;
    }
     
    __attribute ((visibility("hidden"))) void stop()
    {
        printf("Car stop.
    ");
    }

    使用 visibility=default 和 visibility=hidden 分别编译 Car.c.

    可以知道, stop 函数都是隐藏的.

    这个也很好的说明了上面两个问题.

    注意: g++-4.9 改为 gcc-4.9也是一样的.

    另外, 除了 default 和 hidden, 还有 internal, protected.请关注后续讨论.

  • 相关阅读:
    C/C++,彩色图像小游戏。
    js 调用百度地图,并且定位用户地址,显示省市区街,经纬度
    C/C++ 双精度double 数据相加出错缺陷解释
    辗转相除法求最大公约数,非goto
    如何用 js 获取table 或者其他块状标签的 宽和高
    如何用 ajax 连接mysql数据库,并且获取从中返回的数据。ajax获取从mysql返回的数据。responseXML分别输出不同数据的方法。
    C++ 连接数据库的入口和获取列数、数据
    Win10:如何修改双网卡的优先级?
    如何拉动内需,击中客户深层需求,4个经典案例分析!
    单点登录SSO简介
  • 原文地址:https://www.cnblogs.com/wlzy/p/9733090.html
Copyright © 2011-2022 走看看