zoukankan      html  css  js  c++  java
  • gcc __attribute__关键字举例之visibility【转】

    转自:https://blog.csdn.net/starstarstone/article/details/7493144?utm_source=tuicool&utm_medium=referral

    visibility用于设置动态链接库中函数的可见性,将变量或函数设置为hidden,则该符号仅在本so中可见,在其他库中则不可见。

        g++在编译时,可用参数-fvisibility指定所有符号的可见性(不加此参数时默认外部可见,参考man g++中-fvisibility部分);若需要对特定函数的可见性进行设置,需在代码中使用__attribute__设置visibility属性。

        编写大型程序时,可用-fvisibility=hidden设置符号默认隐藏,针对特定变量和函数,在代码中使用__attribute__ ((visibility("default")))另该符号外部可见,这种方法可用有效避免so之间的符号冲突。

        下面是visibility的实例,这里extern “C”可以省略(另外两篇文章gcc __attribute__关键字举例之alias C++覆盖系统函数的方法 中extern "C"不可用省略)。

        值得注意的是,visibility2.cc中可以调用fun1,原因是visibility1.o和visibility2.o同属于一个so文件。

        visibility1.cc:

    1. #include <stdio.h>
    2. extern "C" void fun1()
    3. {
    4. printf("in %s ",__FUNCTION__);
    5. }
    6. __attribute__ ((visibility("hidden"))) void fun1();//若编译此文件时使用了参数-fvisibility=hidden,则此行可以省略


        visibility2.cc:

    1. #include <stdio.h>
    2. extern "C" void fun1();
    3. extern "C" void fun2()
    4. {
    5. fun1();
    6. printf("in %s ",__FUNCTION__);
    7. }
    8. __attribute__ ((visibility("default"))) void fun2();//若编译此文件时没有使用参数-fvisibility或设置参数-fvisibility=default,则此行可以省略


        main.cc:

    1. extern "C" void fun1();
    2. extern "C" void fun2();
    3. int main()
    4. {
    5. fun1();
    6. fun2();
    7. return 0;
    8. }


        Makefile:

    all:test
    test:main.o libvisibility.so
            g++ -o test main.o -lvisibility -L .
    main.o::main.cc
            g++ -c main.cc
    libvisibility.so:visibility1.o visibility2.o
            g++ -shared -o libvisibility.so visibility1.o visibility2.o
    visibility1.o:visibility1.cc
            g++ -fvisibility=hidden -fPIC -c visibility1.cc
    visibility2.o:visibility2.cc
            g++ -fvisibility=hidden -fPIC -c visibility2.cc
    clean:
            rm -f *.o *.so test
    


    编译和输出:

    $ make
    g++ -c main.cc
    g++ -fvisibility=hidden -fPIC -c visibility1.cc
    g++ -fvisibility=hidden -fPIC -c visibility2.cc
    g++ -shared -o libvisibility.so visibility1.o visibility2.o
    g++ -o test main.o -lvisibility -L .
    main.o: In function `main':
    main.cc:(.text+0x5): undefined reference to `fun1'
    collect2: ld returned 1 exit status
    make: *** [test] Error 1 
    


    可以看到,main()中可以不可用调用fun1,可以调用fun2,因为fun1已经设置为外部不可见,fun2设置为外部可见。

    使用readelf对各个.o文件分析可以看到,fun1的Vis属性为HIDDEN,fun2的Vis属性为DEFAULT:

    $ readelf -s visibility1.o|grep fun
         6: 0000000000000007     5 OBJECT  LOCAL  DEFAULT    6 _ZZ4fun1E12__FUNCTION__
        12: 0000000000000000    30 FUNC    GLOBAL HIDDEN    2 fun1
    
    $ readelf -s visibility2.o|grep fun
         6: 0000000000000007     5 OBJECT  LOCAL  DEFAULT    6 _ZZ4fun2E12__FUNCTION__
        12: 0000000000000000    35 FUNC    GLOBAL DEFAULT    2 fun2
        15: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND fun1
    
    $ readelf -s libvisibility.so|grep fun
         9: 00000000000006ac    35 FUNC    GLOBAL DEFAULT   12 fun2
        41: 000000000000071d     5 OBJECT  LOCAL  DEFAULT   14 _ZZ4fun1E12__FUNCTION__
        43: 0000000000000729     5 OBJECT  LOCAL  DEFAULT   14 _ZZ4fun2E12__FUNCTION__
        48: 000000000000068c    30 FUNC    LOCAL  HIDDEN   12 fun1
        54: 00000000000006ac    35 FUNC    GLOBAL DEFAULT   12 fun2
    

    参考:

    Function Attributes

    Visibility Pragmas

    GCC扩展 __attribute__ ((visibility("hidden")))

  • 相关阅读:
    一个程序员的职业规划
    基于Andoird 4.2.2的Account Manager源代码分析学习:创建选定类型的系统帐号
    [置顶] C++学习书单
    js快速分享代码
    The declared package does not match the expected package
    IBM Rational Appscan Part 1
    IBM Rational Appscan: Part 2 ---reference
    阅读redis源代码的一些体会
    18 Command Line Tools to Monitor Linux Performance
    代码规范
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/9241874.html
Copyright © 2011-2022 走看看