[LINUX] Was ist eine C-Sprachbibliothek? Welche Informationen sind für die Öffentlichkeit zugänglich?

** Einführung **

Das Thema dieses Artikels ist wie folgt.

  1. Welche Informationen über die Bibliothek sind nach außen offen? Grober Kommentar
  2. So überprüfen Sie öffentliche Informationen
  3. Wie man öffentliche Informationen einschränkt

Der Inhalt ist ein tiefer Einblick in diesen Artikel. Ich werde noch einmal zusammenfassen, wo es sich um eine Bibliothek und eine öffentliche API handelt

** Welche Informationen über die Bibliothek werden nach außen veröffentlicht? ** **.

** Was ist eine Bibliothek? ** **.

Das Programm beginnt mit der Hauptfunktion und realisiert die Funktion des Programms unter Verwendung der von main aufgerufenen Funktionen und der verwendeten Daten. Es funktioniert nicht ohne die Funktionen, die von der Hauptfunktion aufgerufen werden sollen, und die verwendeten Daten, sodass es immer irgendwo im Programm eine Entität gibt.

program.png

Wenn Sie ein Programm auf diese Weise erstellen, gibt es Fälle, in denen Sie plötzlich Ecken schneiden möchten. Sie müssen jedes Mal genau dieselbe Funktion verwenden. Die Bibliothek ** ist ein Mechanismus, um solche ** genau die gleichen Funktionen zusammenzustellen.

ライブラリ.png

** Um die Bibliothek zu benutzen **

Die Bibliothek wird beim Kompilieren des Programms einer Bibliothek mit dem Namen ** Bibliothekslink ** oder ** Link ** zugeordnet.

Um die Bibliothek zu verknüpfen, muss die Bibliothek Folgendes tun.

Sie müssen Informationen über das in der Abbildung verwendete apllo () und die Tassen offenlegen. Dies ist das Hauptthema dieser Zeit, ** Informationen, die für die Öffentlichkeit zugänglich sind **. Wenn die Funktionsinformationen durch diese Verknüpfung aufgelöst werden, kann das Programm die Bibliothek verwenden. Zu diesem Zeitpunkt unterscheidet sich die Verwendungsmethode je nach Art der Bibliothek.

** Statische Bibliothek (.a) **

Es ist eine Bibliothek in einem Format, das das Programm zum Zeitpunkt der Kompilierung importiert. Da es zur Erstellungszeit im Programm enthalten ist, ist die Funktion bereits vorhanden, wenn das Programm ausgeführt wird, sodass Sie das Programm ohne nachzudenken verwenden können **. Da die gesamte halbseitige Bibliothek importiert wird, ** wird die Größe erhöht **.

static_lib.png

** Gemeinsame Bibliothek (.so) **

Das Programm speichert zur Kompilierungszeit nur die Bibliotheksinformationen und ordnet sie zur Laufzeit der Zieldatei zu. (Es heißt ** Verknüpfung von Bibliotheken **)

shared_lib.png

Im Fall einer gemeinsam genutzten Bibliothek verfügt das Programm nur über die Bibliotheksinformationen. Daher muss die Zielbibliothek bei der Ausführung des Programms verknüpft werden.

Dieser Mechanismus ist [wie folgt](https://qiita.com/developer-kikikaikai/items/f6f87b2d1d7c3e14fb52#%E5%9F%BA%E6%9C%AC%E7%9A%84%E3% 81% AAlinux% E3% 81% AE% E5% 8B% 95% E7% 9A% 84% E3% 83% A9% E3% 82% A4% E3% 83% 96% E3% 83% A9% E3% 83% AA% E3% 83% AA% E3% 83% B3% E3% 82% AF% E3% 81% AB% E9% 96% A2% E3% 81% 99% E3% 82% 8B% E4% BB% 95% E7% B5% 84% E3% 81% BF).

Einfach ausgedrückt ist es in Ordnung, wenn der Pfad der Zielbibliothek vom Befehl ldd ausgegeben wird. Wenn nicht, müssen Sie den Pfad in der Build- oder Umgebungsvariablen für die Bibliothek übergeben. Es ist in Ordnung, wenn die rechte Seite von => wie unten gezeigt irgendwo gebunden ist.

$ ldd /usr/bin/curl
        linux-vdso.so.1 (0x00007ffe307ac000)
        libcurl.so.4 => /usr/lib/x86_64-linux-gnu/libcurl.so.4 (0x00007f85cce4e000)
...
        libssl.so.1.1 => /usr/lib/x86_64-linux-gnu/libssl.so.1.1 (0x00007f85cbb4b000)
        libcrypto.so.1.1 => /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1 (0x00007f85cb6d3000)
...
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f85c6c95000)

** Ergänzung **

Nachtrag 2018/05/16

~~ Ich habe den Artikel versehentlich verwendet und ~~ den offiziellen Namen der Bibliothek. Ich möchte diese Gelegenheit nutzen, um zusammenzufassen.

Name Beispiel Überblick
Statische Bibliothek Linux xx.a, Windows xxx.lib Bibliothek in dem im Programm enthaltenen Format
Gemeinsame Bibliothek Linux xx.so, Windows xxx.dll Bibliothek beim Programmstart verknüpft
Dynamische Bibliothek Linux dlopen(), Windows LoadLibrary() Bibliothek zum Verknüpfen, während das Programm ausgeführt wird

xx.a, Es fühlt sich wie eine dynamische Bibliothek an, weil es fließend in verschiedene Programme integriert ist. Ich mache oft einen Fehler, wenn ich mein Gehirn nicht wie "Dynamisch ... Oh, es ist ein Name, der von einer anderen Art der Aufnahme stammt" organisiere. ... vielleicht nur ich. Ja

** Informationen zu Bibliotheken, die der externen externen Verknüpfung ausgesetzt sind **

Ich machte einen langen Schritt. Ab hier ist die Produktion. Ich habe etwas gesagt, aber welche Informationen werden nach außen weitergegeben? Programmmäßig ist es ** mit externer Verknüpfung **. (Wagen Sie es, den Ausdruck ** öffentliche Informationen in diesem Artikel ** zu verwenden)

Um es grob in C-Sprache auszudrücken: ** Die Grundlagen sind Funktionen und Variablen **, die nicht statisch definiert sind. Beachten Sie, dass sich die Denkweise zwischen C und C ++ geringfügig unterscheidet. ** Wenn die Klasse nicht statisch ist, kann C ++ interne Variablen möglicherweise nicht gut verarbeiten, selbst wenn die Methode statisch ist **. Korrekt. Andere ** Es ist notwendig, den Unterschied zwischen statisch und statisch zu verstehen, was in C ++ keine öffentlichen Informationen sind **. Weitere Informationen zu C ++ finden Sie unter hier. Dieser Artikel konzentriert sich auf C.

Das Problem mit dieser Bedingung allein ist, dass ** alle Funktionen, die für Dateien in der Bibliothek verwendet werden, öffentliche Informationen sind! **. Danach zeigen wir Ihnen, wie Sie öffentliche Informationen überprüfen und einschränken können. Es überschneidet sich teilweise mit diesem Artikel.

** So überprüfen Sie öffentliche Informationen (externe Verknüpfung) **

** nm Befehl **

Sie können die öffentlichen Informationen mit dem Befehl nm überprüfen.

Zum Beispiel:

Überprüfen Sie zunächst das Programm selbst.

$nm -D test
                 w __cxa_finalize
                 w __gmon_start__
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 U __libc_start_main
                 U memcmp
                 U __printf_chk
                 U publisher_free
                 U publisher_new
                 U publisher_publish
                 U publisher_subscribe
                 U publisher_unsubscribe
                 U puts
                 U __stack_chk_fail

Kleinbuchstaben sind eine lokale Funktion, Details werden weggelassen. Das Problem ist das Kapital. ** U ist ungelöst **, dh eine Funktion, die zur Laufzeit als gemeinsam genutzte Bibliothek verknüpft werden muss. Da publisher_XXX usw. selbst erstellte Funktionen sind, können sie nur verwendet werden, wenn sie veröffentlicht werden.

Auf der anderen Seite sieht die verknüpfte Bibliothek so aus

nm  .libs/libpublisher.so
...
0000000000000f90 t dputil_list_pop
0000000000000f50 t dputil_list_pull
0000000000000f20 t dputil_list_push
0000000000000ee0 t dputil_lock
0000000000000f00 t dputil_unlock
...
                 U pthread_mutex_init@@GLIBC_2.2.5
                 U pthread_mutex_lock@@GLIBC_2.2.5
                 U pthread_mutex_unlock@@GLIBC_2.2.5
                 U __pthread_register_cancel@@GLIBC_2.3.3
                 U __pthread_unregister_cancel@@GLIBC_2.3.3
                 w __pthread_unwind_next@@GLIBC_2.3.3
...
00000000000009b0 T publisher_free
0000000000202090 b publisher_g
0000000000000a00 T publisher_new
0000000000000b20 T publisher_publish
0000000000000a90 T publisher_subscribe
0000000000000ae0 T publisher_unsubscribe
0000000000000910 t register_tm_clones
                 U __sigsetjmp@@GLIBC_2.2.5
                 U __stack_chk_fail@@GLIBC_2.4
0000000000202078 d __TMC_END__

** T ist öffentliche Information **. Es gibt einen publisher_xxx richtig. Mit anderen Worten, es ist in Ordnung, wenn "libpublisher.so.0.0.0" zur Laufzeit verknüpft werden kann. pthread_mutex_init usw. ist ** U **, aber da dies eine Standardfunktion ist, ist sie normal verknüpft.

Übrigens ist es in dputil_xxx und libpublisher.so in der obigen lokalen Funktion enthalten, aber es ist tatsächlich eine statische Bibliotheksfunktion.

$ nm .libs/libdputil.a

dp_util.o:
00000000000000b0 T dputil_list_pop
0000000000000070 T dputil_list_pull
0000000000000040 T dputil_list_push
0000000000000000 T dputil_lock
0000000000000020 T dputil_unlock
                 U _GLOBAL_OFFSET_TABLE_
                 U pthread_mutex_lock
                 U pthread_mutex_unlock

Die Tatsache, dass dies nicht ** U ** ist, bedeutet auch, dass libpublisher.so es zur Kompilierungszeit aufgenommen hat.

** objdump Befehl **

Sie können die vom Programm gespeicherten Informationen auch mit dem Befehl objdump sichern. Da Sie andere Informationen als Links überprüfen können, scheint es für die Analyse nützlich zu sein, wenn Sie sie beherrschen (= Ich denke, dass es kurz vor dem Lesen des Assemblers steht).

objdump -t libpublisher.so.0.0.0

libpublisher.so.0.0.0:     file format elf64-x86-64

SYMBOL TABLE:
...
0000000000000ee0 l     F .text  0000000000000012              dputil_lock
...
0000000000000000       F *UND*  0000000000000000              free@@GLIBC_2.2.5
...
0000000000000ae0 g     F .text  0000000000000032              publisher_unsubscribe
...

Wenn ** g wie folgt angehängt ist, sind öffentliche Informationen **, ** l lokal **, ** UND ungelöst **. Bitte verwenden Sie die Durchgangsrichtung für die Bedeutung detaillierter Wörter.

** So beschränken Sie öffentliche Informationen (externe Verknüpfung) **

** - API-Einschränkungen nach Versionsskript **

Gleich wie im vorherigen Artikel. ** Geben Sie die Funktion an, die in XXX.map veröffentlicht werden soll, und fügen Sie -Wl, --version-script, libtimelog.map zu den Erstellungsoptionen hinzu **.

LDFLAGS+=-Wl,--version-script,libtimelog.map

libtimelog.map


{
  global:
    timetestlog_init;
    timetestlog_store_printf;
    timetestlog_exit;
  local: *;
};

Es ist einfach und leicht zu verstehen, aber das Erstellen einer Einstellungsdatei ist mühsam.

-fvisibility=hidden

Wenn Sie "-fvisibility = hidden" angeben, werden alle Funktionen zuerst privat gemacht. Fügen Sie dann __attribute __ ((Sichtbarkeit (" Standard "))) nur zu dem hinzu, was Sie benötigen, und veröffentlichen Sie es! Es ist eine Technik namens. Es ist eine perfekte Möglichkeit für diejenigen, die gerne mit Codierungsregeln steuern.

In libpublisher.so wird bei der Einführung von nm verwendet, -fvisibility = hidden angegeben,int __attribute__ ((Sichtbarkeit ("Standard"))) publisher_new (size_t content_num)für jede öffentliche Funktion Ich habe es so spezifiziert und gebaut.

Daher bin ich neugierig, dass die API von libdputil.a T ist, aber ich kann es auf ein schönes Gefühl beschränken.

nm -D .libs/libpublisher.so.0.0.0
0000000000202098 B __bss_start
                 U calloc
                 w __cxa_finalize
0000000000001210 T dputil_list_pop
00000000000011d0 T dputil_list_pull
00000000000011a0 T dputil_list_push
0000000000001160 T dputil_lock
0000000000001180 T dputil_unlock
0000000000202098 D _edata
00000000002020c0 B _end
0000000000001224 T _fini
                 U free
                 w __gmon_start__
0000000000000a00 T _init
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 U pthread_mutex_init
                 U pthread_mutex_lock
                 U pthread_mutex_unlock
                 U __pthread_register_cancel
                 U __pthread_unregister_cancel
                 w __pthread_unwind_next
0000000000000c10 T publisher_free
0000000000000c80 T publisher_new
0000000000000da0 T publisher_publish
0000000000000d10 T publisher_subscribe
0000000000000d60 T publisher_unsubscribe
                 U __sigsetjmp
                 U __stack_chk_fail

** Mein Geschmack **

Ich bevorzuge ** - Versionsskript **, weil ich beim Schreiben von Code nicht öffentlich / privat sein muss. Es fällt mir leicht, sie alle zusammen in conf zu schreiben.

20.05.2018 Nachtrag Mir gefällt auch die Tatsache, dass dies mit einem Skript automatisiert werden kann. Ich habe ein Skriptbeispiel erstellt, das das Include-Verzeichnis durchsucht und ein Versionsskript erstellt. Die Reaktion auf das Makro ist nicht gut, aber ich denke, es kann so verwendet werden, wie es ist.

#!/bin/sh

output_conf_map() {
        #{
        #  global:
        #    function_name;
        # ...
        #  local: *;
        #}

        #only get function list from header file
        HEADER_FUNC_LIST=`grep "[a-zA-Z](" -r $1 | grep -v "@brief" | grep -v "#define" | awk -F"(" '{print $1}' | awk -F " " '{print $NF}'`
        #template
        echo "{"
        echo "  global:"

        #show all function
        for data in $HEADER_FUNC_LIST
        do
                echo "    $data;"
        done

        #template end
        echo "  local: *;"
        echo "};"
}

INCLUDE_LIST=`find . -name include`
for inc_dir in $INCLUDE_LIST
do
        echo $inc_dir
        output_conf_map  $inc_dir
done

** Eindruck **

Zuerst von der Entschuldigung. Der Grund für die Erstellung dieses Artikels ist Artikel zu Einschränkungen bei der Veröffentlichung von Bibliotheken ) Wurde eine Zen-Frage und -Antwort wie "Warum gibt es verschiedene Formen der öffentlichen API-Einschränkung für gemeinsam genutzte Bibliotheken? Was ist überhaupt öffentlich? Warum leben Menschen?" Gepostet und kommentiert. Es war der Anfang. Daher wollte ich die Frage zunächst genau in der Sprache des Programmbereichs beantworten.

Es war jedoch unmöglich, über diesen Bereich zu sprechen, ohne tief zu graben, und da die Frage und Antwort des Zen wirklich begann, dachte ich erneut: "Was war die Bibliothek, die ich organisieren wollte?" Dank dessen habe ich das Gefühl, dass der flauschige Teil gelöscht wurde, unabhängig davon, ob er als oberer Middleware-Entwickler verstanden wird oder nicht.

Danach habe ich viele Probleme in der Bibliothek, aber wenn ich weiß, wie ich es überprüfen kann, wird meine Angst nachlassen. Besonders um OSS. ldd, nm super bequem

Referenz

Eine Site, die erklärt, wie man sehr sorgfältig mit Speicher umgeht. Kane: Oh, das ist der, von dem ich süchtig bin, wenn ich tiefer grabe. Wenn Sie nach der Codegröße gefragt werden|Dinge, die man in der Schule nicht erzählen kann| [Technische Säulensammlung]Eingebautes Tor|Uquest Co., Ltd.

Handhabung von Funktionen vom Assembler aus gesehen Eine Geschichte, in der man leicht vor der neuesten Technologie besiegt werden kann, wenn man versucht, alte Techniken zu zeigen | Mögliche Eria

Definition der externen Verknüpfung https://msdn.microsoft.com/ja-jp/library/k8w8btzz.aspx

So beschränken Sie die Bibliotheksfreigabe in C ++ So schreiben Sie eine gemeinsam genutzte Bibliothek im C ++ - Format (gcc edition) --Qiita

Wie man nm liest Liste der Symbole aus dem Objekt mit dem Befehl nm anzeigen - Qiita

Bibliotheksname [Bibliothek - Grundkenntnisse der Kommunikationsbegriffe](http://www.wdic.org/w/TECH/ Library)

Recommended Posts

Was ist eine C-Sprachbibliothek? Welche Informationen sind für die Öffentlichkeit zugänglich?
[Einführung in Python] Was ist Python, die derzeit leistungsstärkste Programmiersprache?
[Einführung in Python] Was ist der Unterschied zwischen einer Liste und einem Taple?
Verwendung der C-Bibliothek in Python
Es ist ein Mac. Was ist der Linux-Befehl Linux?
So zeigen Sie das Änderungsdatum einer Datei in C-Sprache bis zu Nanosekunden an
So verwenden Sie eine Bibliothek, die ursprünglich nicht in Google App Engine enthalten war
Was ist eine rationale Entscheidung, die die Chancen maximiert, ein "ideales Zuhause" zu finden?
[Einführung in Python] Was ist die empfohlene Pip-Installationsmethode für das Paketverwaltungssystem?
So beschränken Sie die API, die in der gemeinsam genutzten Linux-Bibliothek in C-Sprache veröffentlicht werden soll
Versuchen Sie, ein Python-Modul in C-Sprache zu erstellen
Eine grobe Einführung in die neuronale maschinelle Übersetzungsbibliothek
Programmiersprache, die die Menschen vor NHK schützt
[Python] Eine praktische Bibliothek, die Kanji in Hiragana konvertiert
Ich hatte das Gefühl, dass ich den Python-Code nach C ++ 98 portiert habe.
Was ist ein empfohlener Motor? Zusammenfassung der Typen
Für mich als Django-Anfänger (2) - Was ist MTV?
Was ist eine Distribution?
Was ist ein Terminal?
Was ist ein Hacker?
Was ist ein Zeiger?
Belüftung ist wichtig. Was ich getan habe, um die CO2-Konzentration im Raum aufzuzeichnen
Was tun, wenn ein nicht in pom.xml definiertes Glas zu einem fehlenden Artefakt wird?
Was ist der Unterschied zwischen symbolischen und harten Links?
Ein Memorandum zur Registrierung der in Hy in PyPI geschriebenen Bibliothek
Generieren Sie mit apg ein leicht zu merkendes Passwort
Ich habe versucht, die Zeit und die Zeit der C-Sprache zu veranschaulichen
Gibt es eine Verzerrung in den Zahlen, die in den Fibonacci-Zahlen erscheinen?
[C-Sprache] Close () Es ist gefährlich, es erneut zu versuchen, wenn es fehlschlägt
Die Geschichte, den privaten Schlüssel mit chmod auf 600 zu setzen
[Pyro] Statistische Modellierung mit der probabilistischen Programmiersprache Pyro ~ What is Pyro ~
Verwenden Sie eine Skriptsprache für ein komfortables C ++ - Leben - OpenCV-Port Python zu C ++ -
Übergeben Sie die OpenCV-Daten der ursprünglichen C ++ - Bibliothek an Python
Gibt es ein Geheimnis in der Häufigkeit der Umfangszahlen?
Was tun, wenn Sie eine Binärdatei katzen oder verfolgen und das Terminal verstümmelt ist?
Ich habe versucht, eine Site zu erstellen, mit der die aktualisierten Informationen von Azure einfach angezeigt werden können
Hypothese / Verifikation (176) Wie man ein Lehrbuch macht, das einfacher ist als "Das einfachste Lehrbuch für Quantencomputer"
Was tun, wenn ein Teil des Hintergrundbilds transparent wird, wenn Sie transparente Bilder mit Pillow kombinieren?
Eine kleine süchtig machende Geschichte mit den Berechtigungen des von expdp angegebenen Verzeichnisses (für Anfänger)
Wie man eine schreckliche Bibliothek austrickst und benutzt, die global in einer Flasche aufbewahrt werden soll
Verwenden Sie eine Skriptsprache für ein komfortables C ++ - Leben. 5 - Verwenden Sie die integrierte Spyder-Umgebung, um numerische Daten zu überprüfen.
Was tun, wenn der Benutzername geändert wird und der Pfad der pyenv-Bibliothek nicht übergeben wird?
Was ist die Aktivierungsfunktion?
Was ist ein Entscheidungsbaum?
Was ist ein Kontextwechsel?
Was ist ein Superuser?
Was ist ein Systemaufruf?
[Definition] Was ist ein Framework?
Was ist die Schnittstelle für ...
Versuchen Sie, eine Sprache auszuwählen
Was ist eine Rückruffunktion?
Was ist die Rückruffunktion?
Das Bild ist Namekuji
2. SmartHR-Bibliothek kiji wird verwendet, um e-Gov (öffentliche Materialien von e-Gov) auszuführen
[AWS] Was tun, wenn der Ping-Befehl eine "Zeitüberschreitung" verursacht?
[C-Sprache] [Linux] Versuchen Sie, einen einfachen Linux-Befehl zu erstellen. * Fügen Sie einfach hinzu! !!