zoukankan      html  css  js  c++  java
  • Linux下gcc编译控制动态库导出函数小结

    Linux下gcc编译控制动态库导出函数小结

    来源 https://www.cnblogs.com/lidabo/p/5703890.html

    根据说明文档“How To Write Shared Libraries"介绍,

    有四种方法:

    1. 在方法声明定义时,加修饰:__attribute__((visibility("hidden")))

    就是说将不公开的函数都加上这个属性,没加的就是可见的

    2. gcc 在链接时设置 -fvisibility=hidden,则不加 visibility声明的都默认为hidden; gcc默认设置 -fvisibility=default,即全部可见;

    在gcc中加了这个设置之后表示所有的函数都是对外不可见了,然后在代码里面对于想公开的函数加上 __attribute__((visibility("default")))

    3. 使用export map,gcc -Wl,--version-script=export.map, 在export.map中指定

    {

    global:export_func;

    local:*;

    };

    则除了export_func外,全部为内部可见;

    4. 使用libtool的export-symbols选项,没试过,略;

    以上方法,对于gcc的visibility功能需要 gcc 4以上版本,

    常见的宏,用于等同于 windows下的 __declspec(dllexport)(摘自:http://gcc.gnu.org/wiki/Visibility):

    #if defined _WIN32 || defined __CYGWIN__
    
      #ifdef BUILDING_DLL
    
        #ifdef __GNUC__
    
          #define DLL_PUBLIC __attribute__((dllexport))
    
        #else
    
          #define DLL_PUBLIC __declspec(dllexport) // Note: actually gcc seems to also supports this syntax.
    
        #endif
    
      #else
    
        #ifdef __GNUC__
    
          #define DLL_PUBLIC __attribute__((dllimport))
    
        #else
    
          #define DLL_PUBLIC __declspec(dllimport) // Note: actually gcc seems to also supports this syntax.
    
      #endif
    
      #define DLL_LOCAL
    
    #else
    
      #if __GNUC__ >= 4
    
        #define DLL_PUBLIC __attribute__ ((visibility("default")))
    
        #define DLL_LOCAL  __attribute__ ((visibility("hidden")))
    
      #else
    
        #define DLL_PUBLIC
    
        #define DLL_LOCAL
    
      #endif
    
    #endif
    
    
    
    实践中发现几个有意思的东西[实验环境为ubuntu 9.10, gcc 4.4.1]:
    
    1. gcc -fvisibility=hidden 只在链接时传入的.c文件起作用,对.o文件不其作用;
    
    比如test.c test1.c, 使用以下命令:
    
    gcc -shared -fvisibility=hidden -o test.so test.c test1.c
    
    和命令
    
    gcc -c test.c test1.c
    
    gcc -shared -fvisibility=hidden -o test.so test.o test1.o
    
    生成的test.so中的对应可见性是不一样的, 使用“readelf -s test.so”查看发现:
    
    第一个达到预期目的,即将两个.c文件中的functions设为HIDDEN,
    
    而第2个则不行,-fvisibility=hidden不起作用;
    
    再用gcc -shared -fvisibility=hidden -o test.so test.o test1.c
    
    生成的so,则可发现test1.c中的函数为HIDDEN,但test.o中的函数仍为DEFAULT;
    
    
    
    2. 实验通过export map的方法,通过readelf总是发现函数仍然可见,后来搜索发现:
    
    需同时使用ld --retain-symbols-file --version-script 两个选项方能达到 使得elf文件中的.dynsym和.symtab
    
    中的符号表都得到控制;其中--retain-symbols-file控制静态符号表,--version-script则对应dynamic符号表;
    另外可以参考 http://blog.csdn.net/shuiyingzi5/article/details/8108190
    
    
    
    
    转自 http://blog.csdn.net/zdragon2002/article/details/6061962

    =============== End

  • 相关阅读:
    Droptiles
    10 条建议让你创建更好的 jQuery 插件
    15个值得开发人员关注的jQuery开发技巧和心得
    8 个最好的 jQuery 树形 Tree 插件
    jQuery的发展史,你知道吗?
    20+个可重复使用的jQuery代码片段
    10 款基于 jQuery 的切换效果插件推荐
    关于浏览器事件的思考
    JS实现复制到剪贴板(兼容FF/Chrome/Safari所有浏览器)
    Javascript函数声明与函数表达式的区别
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/12510201.html
Copyright © 2011-2022 走看看