GNU/Linux >> Znalost Linux >  >> Linux

Jak funguje dynamické linkování, jeho použití a jak a proč byste udělali dylib

Hlavním rozdílem je, že do aplikace zahrnete statické propojené knihovny. Jsou propojeny při vytváření aplikace. Dynamické knihovny jsou propojeny za běhu, takže je nemusíte zahrnout do vaší aplikace. V dnešní době se dynamické knihovny používají ke zmenšení velikosti aplikací tím, že mají mnoho dynamických knihoven na každém počítači.

Dynamické knihovny také umožňují uživatelům aktualizovat knihovny bez přestavby klientských aplikací. Pokud je v knihovně, kterou používáte ve své aplikaci, nalezena chyba a je staticky propojená, budete muset aplikaci znovu sestavit a znovu ji vydat všem svým uživatelům. Pokud je v dynamicky propojené knihovně nalezena chyba, všichni vaši uživatelé si stačí aktualizovat své knihovny a vaše aplikace aktualizaci nepotřebuje.


Když je kompilován program C++. Musí obsahovat odkazy na funkce a kód knihovny C++ (řekněme například kód knihovny).

Předpokládejme, že máme hypotetickou sdílenou knihovnu s názvem libdyno.so . Nakonec do něj budete moci nahlédnout pomocí objdump nebo nm .

objdump --syms libdyno.so

Dnes to můžete udělat ve svém systému s jakoukoli sdílenou knihovnou. objdump na MAC se nazývá gobjdump a přichází s vařením v binutils balík. Zkuste to na počítači Mac...

gobjdump --syms /usr/lib/libz.dylib

Nyní můžete vidět, že symboly jsou obsaženy ve sdíleném objektu. Když link se sdíleným objektem obvykle používáte něco jako

g++ -Wall -g -pedantic -ldyno DynoLib_main.cpp -o dyno_main

Všimněte si -ldyno v tom příkazu. Toto říká kompilátoru (ve skutečnosti linker ld), aby hledal sdílený objektový soubor s názvem libdyno.so kdekoli je běžně hledá. Jakmile najde předmět, může najít symboly, které potřebuje. Neexistuje žádná kruhová závislost, protože jste vývojář požádal o načtení dynamické knihovny zadáním -l vlajka.

Jak a kdy byste použili dynamickou knihovnu? Jak si ho vyrobíte? Stejně jako v tom, co je specifický kompilační příkaz, který se používá k vytvoření takového souboru ze standardního souboru .cpp

Vytvořte soubor s názvem DynoLib.cpp

#include "DynoLib.h"
DynamicLib::DynamicLib() {}
int DynamicLib::square(int a) {
  return a * a;
}

Vytvořte soubor s názvem DynoLib.h

#ifndef DYNOLIB_H
#define DYNOLIB_H
class DynamicLib {
  public:
  DynamicLib();
  int square(int a); 
};
#endif

Zkompilujte je jako sdílenou knihovnu následovně. Toto je specifické pro linux...

g++ -Wall -g -pedantic -shared -std=c++11 DynoLib.cpp -o libdyno.so

Nyní můžete tento objekt zkontrolovat pomocí příkazu, který jsem zadal dříve, tj.

objdump --syms libdyno.so

Nyní vytvořte soubor s názvem DynoLib_main.cpp, který bude propojen s libdyno.so a použijte funkci, kterou jsme v něm právě definovali.

#include "DynoLib.h"    
#include <iostream>     
using namespace std;
int main(void) {
  DynamicLib *lib = new DynamicLib();
  std::cout << "Square " << lib->square(1729) << std::endl;
  return 1;
}

Zkompilujte jej následovně

g++ -Wall -g -pedantic -L. -ldyno DynoLib_main.cpp -o dyno_main
./dyno_main
Square 2989441

Můžete se také podívat na hlavní binární soubor pomocí nm . V následujícím vidím, zda existuje něco s řetězcem square v něm je tedy symbol, který potřebuji z libdyno.so jakýmkoli způsobem odkazováno v mém binárním souboru.

nm dyno_runner |grep square
U _ZN10DynamicLib6squareEi

Odpověď je ano. Velká písmena U znamená nedefinováno, ale toto je název symbolu pro naši čtvercovou metodu ve třídě DynamicLib, kterou jsme vytvořili dříve. Podivně vypadající jméno je způsobeno modifikací jmen, což je jeho vlastní téma.

Jak poznám, na které z nich mám odkazovat staticky jako u souboru regular.o a na které se má odkazovat dynamicky?

Nemusíš to vědět. Specifikujete, s čím chcete propojit, a necháte kompilátor (a linker atd.) dělat práci. Všimněte si -l příznak pojmenovává knihovnu a -L říká, kde hledat. Zde je slušný zápis o tom, jak kompilátor něco najde

gcc Linkage option -L:Alternativní způsoby, jak zadat cestu k dynamické knihovně

Nebo se podívejte na man ld .

K čemu slouží příznaky -L a -l? Co to znamená zadat například příznak -lusb na příkazovém řádku?

Viz výše uvedený odkaz. Toto je z man ld ..

-L searchdir

Přidejte cestu searchdir do seznamu cest, které ld bude hledat archivní knihovny a řídicí skripty ld. Tuto možnost můžete použít kolikrát. Adresáře jsou prohledávány v pořadí, v jakém jsou zadány na příkazovém řádku. Adresáře zadané na příkazovém řádku jsou prohledány před výchozími adresáři. All -Loptions platí pro všechny -l volby, bez ohledu na pořadí, ve kterém se volby objeví. Volby -L nemají vliv na to, jak ld hledá linkerscript, pokud není zadána volba -T.`

Pokud se vám podařilo dostat se sem, vyplatí se dozvědět se o linkeru, tj. ld. Hraje důležitou práci a je zdrojem spousty zmatků, protože většina lidí začíná pracovat s kompilátorem a myslí si, že compiler == linker a to není pravda.


Linux
  1. Proč získáte cp:vynechání chyby adresáře v Linuxu a jak to vyřešit

  2. Co je kurátorství obsahu a jak byste to měli dělat?

  3. Jak vyrobit a aplikovat SVN patch?

  1. Jak zacházet s dynamickými a statickými knihovnami v Linuxu

  2. Jak zkontrolovat, zda je nainstalována sdílená knihovna?

  3. Proč a jak jsou některé sdílené knihovny spustitelné, jako by to byly spustitelné soubory?

  1. Jak spravovat statický a dynamický inventář hostitelů Ansible

  2. Proč jsou data důležitá a jak je chránit

  3. Co je TAM a proč byste jím mohli chtít být?