Sie die Ausgabe von nm
Missverständnis. Blättern Sie durch man nm
und Sie werden Sie lesen, dass das t
Flag bedeutet, das Symbol ist ein lokales (statisches) Symbol in der text
Abschnitt. Der Linker kann es nicht sehen. Wenn es global (extern) wäre, wäre die Flagge T
. Alle vier Funktionen sind also lokal.
Kontrast:
$ clang -shared -fPIC -fvisibility=hidden -o libdefaultvisibility.so defaultvisibility.c
$ nm libdefaultvisibility.so | grep ' t '
0000000000000570 t deregister_tm_clones
0000000000000600 t __do_global_dtors_aux
0000000000200e08 t __do_global_dtors_aux_fini_array_entry
0000000000000640 t frame_dummy
0000000000200e00 t __frame_dummy_init_array_entry
0000000000000670 t mylocalfunction1
0000000000000690 t mylocalfunction2
00000000000006b0 t mylocalfunction3
00000000000006d0 t printMessage
00000000000005b0 t register_tm_clones
mit den -fvisibility=hidden
fallen:
$ clang -shared -fPIC -o libdefaultvisibility.so defaultvisibility.c
$ nm libdefaultvisibility.so | grep ' t '
0000000000000600 t deregister_tm_clones
0000000000000690 t __do_global_dtors_aux
0000000000200e08 t __do_global_dtors_aux_fini_array_entry
00000000000006d0 t frame_dummy
0000000000200e00 t __frame_dummy_init_array_entry
0000000000000700 t mylocalfunction1
0000000000000640 t register_tm_clones
$ nm libdefaultvisibility.so | grep ' T '
0000000000000780 T _fini
00000000000005b0 T _init
0000000000000720 T mylocalfunction2
0000000000000740 T mylocalfunction3
0000000000000760 T printMessage
Dann nur die explizit versteckt mylocalfunction1
lokal bleibt, und die anderen drei sind jetzt global.
Sie sollten nicht erwarten, dass ein mit __attribute__ ((visibility("hidden")))
markiertes Symbol unter allen Umständen von einer gemeinsam genutzten Bibliothek exportiert wird.Das Attribut bedeutet genau , dass es nicht sein wird, ob es explizit auf ein Symbol angewendet wird, wie in diesem Fall oder standardmäßig in Anwesenheit der Linkeroption -fvisibility=hidden
erworben wird.
Wenn Sie nur, dass eine Funktion in dem Beispiel mittels einer visibility
Zuschreibung exportieren möchten würden Sie haben:
#define FOR_EXPORT __attribute__ ((visibility("default")))
Dann:
$ clang -shared -fPIC -fvisibility=hidden -o libdefaultvisibility.so defaultvisibility.c
$ nm libdefaultvisibility.so | grep ' T '
0000000000000720 T _fini
0000000000000550 T _init
00000000000006a0 T mylocalfunction1
Es ist global, weil die explizite Die Zuweisung überschreibt die Befehlszeilenoption und alle anderen Funktionen sind lokal. Vielleicht verwirrend, default
Sichtbarkeit ist immer public.
Und man könnte dies zu erreichen, ohne visibility
Aufgaben an eine Zuflucht - die sind nicht tragbar - einfach alle Funktionen erklärt, die Sie tun nicht als static
exportieren möchten. Dann wird der Compiler würde sich an den Linker in erster Linie nicht aussetzen:
foo.c
#include <stdio.h>
void mylocalfunction1(void)
{
printf("function1\n");
}
static void mylocalfunction2(void)
{
printf("function2\n");
}
static void mylocalfunction3(void)
{
printf("function3\n");
}
static void printMessage(void)
{
printf("Running the function exported from the shared library\n");
}
, mit dem Sie wieder bekommen: -
$ clang -shared -fPIC -o libfoo.so foo.c
$ nm libfoo.so | grep ' T '
00000000000006c0 T _fini
0000000000000550 T _init
00000000000006a0 T mylocalfunction1
Obwohl der Unterschied tut Machen Sie sich in Ihrem Beispiel nicht bemerkbar Sie sollten verstehen, dass während ein lokales/statisches Symbol nicht vom Linker gesehen wird und (daher) nicht für dynamisch verfügbar ist Verknüpfung, ein globales/externes Symbol kann oder kann nicht für dynamische Verknüpfung verfügbar sein. visibility
steuert die Verfügbarkeit von globalen Symbolen für dynamische Verknüpfung, nur.
Danke, in der Tat habe ich die Ausgabe von 'nm' missverstanden, vor allem in Bezug auf' T' vs 't'. Es hat tatsächlich wie erwartet funktioniert. Das Buch, das ich lese, ist ziemlich kurz, um die Ausgabe von 'nm' zu interpretieren, und deshalb war ich mir nicht wirklich sicher, was ich sah. Diese Antwort hat es für mich geklärt. – Max