歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux動態鏈接庫導出函數

近日在項目中遇到一個問題,需要在so庫中控制導出函數,即像windows平台一樣,只允許制定的函數導出,而其他函數需要屏蔽掉。

注意:參考文獻中有一些函數是不能編譯通過的。

編譯環境:gcc 4.4.3

在windows中,我們可以指定__declspec(dllexport)定義來控制導出函數,在linux下,我們也有類似的控制參數。

在GCC幫助文檔 -fvisibility=default|internal|hidden|protected參數下有這樣一段描述:

a superior solution made possible by this option to marking things hidden when the default is public is to make the default hidden and mark things public. This is the norm with DLL's on Windows and with -fvisibility=hidden and "__attribute__ ((visibility("default")))" instead of "__declspec(dllexport)" you get almost identical semantics with identical syntax. This is a great boon to those working with cross-platform projects.

需要了解的是,在linux下,源文件中的所有函數都有一個默認的visibility屬性為public,在編譯命令中加入-fvisibility=hidden參數,會將所有默認的public的屬性變為hidden。此時,如果對函數設置__attribute__ ((visibility("default")))參數,使特定的函數仍然按默認的public屬性處理,則-fvisibility=hidden參數不會對該函數起作用。所以,設置了-fvisibility=hidden參數之後,只有設置了__attribute__ ((visibility("default")))的函數才是對外可見的,如此則效果等同於Visual Studio下的__declspec(dllexport)定義。

下面看一個例子:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
extern int test (int i);
__attribute ((visibility("default"))) int test2 (int i)
{
    test(i);
    printf("this is test2/n");
}
int test3 (int i)
{
    printf("this is test 3/n");
}

此時調用以下命令編譯:

gcc -shared -o test.so -fvisibility=hidden test.c

可以獲得test.so文件,用以下命令查看so文件屬性:

readelf -s test.so

得到以下結果:

Symbol table '.dynsym' contains 12 entries:
  Num:    Value  Size Type    Bind  Vis      Ndx Name
    0: 00000000    0 NOTYPE  LOCAL  DEFAULT  UND
    1: 00000000    0 NOTYPE  WEAK  DEFAULT  UND __gmon_start__
    2: 00000000    0 NOTYPE  WEAK  DEFAULT  UND _Jv_RegisterClasses
    3: 00000000    0 NOTYPE  GLOBAL DEFAULT  UND test
    4: 00000000    0 FUNC    GLOBAL DEFAULT  UND puts@GLIBC_2.0 (2)
    5: 00000000    0 FUNC    WEAK  DEFAULT  UND __cxa_finalize@GLIBC_2.1.3 (3)
    6: 00002014    0 NOTYPE  GLOBAL DEFAULT  ABS _end
    7: 0000200c    0 NOTYPE  GLOBAL DEFAULT  ABS _edata
    8: 0000049c    31 FUNC    GLOBAL DEFAULT  12 test2
    9: 0000200c    0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
    10: 00000380    0 FUNC    GLOBAL DEFAULT  10 _init
    11: 00000508    0 FUNC    GLOBAL DEFAULT  13 _fini
Symbol table '.symtab' contains 56 entries:
  Num:    Value  Size Type    Bind  Vis      Ndx Name
    0: 00000000    0 NOTYPE  LOCAL  DEFAULT  UND
    1: 000000f4    0 SECTION LOCAL  DEFAULT    1
    2: 00000118    0 SECTION LOCAL  DEFAULT    2
    3: 0000015c    0 SECTION LOCAL  DEFAULT    3
    4: 00000198    0 SECTION LOCAL  DEFAULT    4
    5: 00000258    0 SECTION LOCAL  DEFAULT    5
    6: 000002e0    0 SECTION LOCAL  DEFAULT    6
    7: 000002f8    0 SECTION LOCAL  DEFAULT    7
    8: 00000328    0 SECTION LOCAL  DEFAULT    8
    9: 00000370    0 SECTION LOCAL  DEFAULT    9
    10: 00000380    0 SECTION LOCAL  DEFAULT  10
    11: 000003b0    0 SECTION LOCAL  DEFAULT  11
    12: 000003e0    0 SECTION LOCAL  DEFAULT  12
    13: 00000508    0 SECTION LOCAL  DEFAULT  13
    14: 00000524    0 SECTION LOCAL  DEFAULT  14
    15: 00000544    0 SECTION LOCAL  DEFAULT  15
    16: 00001f04    0 SECTION LOCAL  DEFAULT  16
    17: 00001f0c    0 SECTION LOCAL  DEFAULT  17
    18: 00001f14    0 SECTION LOCAL  DEFAULT  18
    19: 00001f18    0 SECTION LOCAL  DEFAULT  19
    20: 00001fe8    0 SECTION LOCAL  DEFAULT  20
    21: 00001ff4    0 SECTION LOCAL  DEFAULT  21
    22: 00002008    0 SECTION LOCAL  DEFAULT  22
    23: 0000200c    0 SECTION LOCAL  DEFAULT  23
    24: 00000000    0 SECTION LOCAL  DEFAULT  24
    25: 00000000    0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    26: 00001f04    0 OBJECT  LOCAL  DEFAULT  16 __CTOR_LIST__
    27: 00001f0c    0 OBJECT  LOCAL  DEFAULT  17 __DTOR_LIST__
    28: 00001f14    0 OBJECT  LOCAL  DEFAULT  18 __JCR_LIST__
    29: 000003e0    0 FUNC    LOCAL  DEFAULT  12 __do_global_dtors_aux
    30: 0000200c    1 OBJECT  LOCAL  DEFAULT  23 completed.7021
    31: 00002010    4 OBJECT  LOCAL  DEFAULT  23 dtor_idx.7023
    32: 00000460    0 FUNC    LOCAL  DEFAULT  12 frame_dummy
    33: 00000000    0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    34: 00001f08    0 OBJECT  LOCAL  DEFAULT  16 __CTOR_END__
    35: 00000544    0 OBJECT  LOCAL  DEFAULT  15 __FRAME_END__
    36: 00001f14    0 OBJECT  LOCAL  DEFAULT  18 __JCR_END__
    37: 000004d0    0 FUNC    LOCAL  DEFAULT  12 __do_global_ctors_aux
    38: 00000000    0 FILE    LOCAL  DEFAULT  ABS test.c
    39: 00001ff4    0 OBJECT  LOCAL  HIDDEN  ABS _GLOBAL_OFFSET_TABLE_
    40: 00002008    0 OBJECT  LOCAL  HIDDEN  22 __dso_handle
    41: 00001f10    0 OBJECT  LOCAL  HIDDEN  17 __DTOR_END__
    42: 000004bb    20 FUNC    LOCAL  HIDDEN  12 test3
    43: 00000497    0 FUNC    LOCAL  HIDDEN  12 __i686.get_pc_thunk.bx
    44: 00001f18    0 OBJECT  LOCAL  HIDDEN  ABS _DYNAMIC
    45: 00000000    0 NOTYPE  WEAK  DEFAULT  UND __gmon_start__
    46: 00000000    0 NOTYPE  WEAK  DEFAULT  UND _Jv_RegisterClasses
    47: 00000508    0 FUNC    GLOBAL DEFAULT  13 _fini
    48: 0000049c    31 FUNC    GLOBAL DEFAULT  12 test2
    49: 0000200c    0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
    50: 00000000    0 NOTYPE  GLOBAL DEFAULT  UND test
    51: 00002014    0 NOTYPE  GLOBAL DEFAULT  ABS _end
    52: 00000000    0 FUNC    GLOBAL DEFAULT  UND puts@@GLIBC_2.0
    53: 0000200c    0 NOTYPE  GLOBAL DEFAULT  ABS _edata
    54: 00000000    0 FUNC    WEAK  DEFAULT  UND __cxa_finalize@@GLIBC_2.1
    55: 00000380    0 FUNC    GLOBAL DEFAULT  10 _init

可以看出,so文件中包含test2()和test3()這兩個函數,並且test2()的屬性為default(即可見),而test3()的屬性則為hidden(不可見)。

Copyright © Linux教程網 All Rights Reserved