Perbedaan utamanya adalah Anda menyertakan pustaka tertaut statis dengan aplikasi Anda. Mereka ditautkan saat Anda membuat aplikasi. Pustaka dinamis ditautkan pada waktu proses, jadi Anda tidak perlu menyertakannya dengan aplikasi Anda. Pustaka dinamis saat ini digunakan untuk mengurangi ukuran aplikasi dengan memiliki banyak pustaka dinamis di komputer semua orang.
Pustaka dinamis juga memungkinkan pengguna memperbarui pustaka tanpa membuat ulang aplikasi klien. Jika bug ditemukan di pustaka yang Anda gunakan di aplikasi dan ditautkan secara statis, Anda harus membuat ulang aplikasi dan menerbitkannya kembali ke semua pengguna. Jika bug ditemukan di pustaka yang ditautkan secara dinamis, semua pengguna Anda hanya perlu memperbarui pustaka mereka dan aplikasi Anda tidak memerlukan pembaruan.
Ketika program C++ dikompilasi. Itu harus memiliki referensi ke fungsi dan kode pustaka C++ (misalkan kode untuk pustaka).
Asumsikan kita memiliki pustaka bersama hipotetis yang disebut libdyno.so
. Pada akhirnya Anda akan dapat mengintip ke dalamnya menggunakan objdump
atau nm
.
objdump --syms libdyno.so
Anda dapat melakukannya hari ini di sistem Anda dengan pustaka bersama apa pun. objdump
pada MAC disebut gobjdump
dan dilengkapi dengan minuman di binutils
kemasan. Coba ini di mac...
gobjdump --syms /usr/lib/libz.dylib
Anda sekarang dapat melihat bahwa simbol terkandung dalam objek bersama. Saat Anda link
dengan objek bersama Anda biasanya menggunakan sesuatu seperti
g++ -Wall -g -pedantic -ldyno DynoLib_main.cpp -o dyno_main
Perhatikan -ldyno
dalam perintah itu. Ini memberi tahu kompiler (benar-benar linker ld) untuk mencari file objek bersama yang disebut libdyno.so
di mana pun biasanya mencari mereka. Setelah menemukan objek itu, ia kemudian dapat menemukan simbol yang dibutuhkannya. Tidak ada ketergantungan melingkar karena Anda sebagai pengembang meminta perpustakaan dinamis untuk dimuat dengan menentukan -l
bendera.
Bagaimana dan kapan Anda akan menggunakan pustaka dinamis? Bagaimana Anda membuatnya? Seperti apa perintah kompilasi khusus yang digunakan untuk menghasilkan file seperti itu dari file .cpp standar
Buat file bernama DynoLib.cpp
#include "DynoLib.h"
DynamicLib::DynamicLib() {}
int DynamicLib::square(int a) {
return a * a;
}
Buat file bernama DynoLib.h
#ifndef DYNOLIB_H
#define DYNOLIB_H
class DynamicLib {
public:
DynamicLib();
int square(int a);
};
#endif
Kompilasi mereka menjadi perpustakaan bersama sebagai berikut. Ini khusus linux...
g++ -Wall -g -pedantic -shared -std=c++11 DynoLib.cpp -o libdyno.so
Anda sekarang dapat memeriksa objek ini menggunakan perintah yang saya berikan sebelumnya yaitu
objdump --syms libdyno.so
Sekarang buat file bernama DynoLib_main.cpp yang akan ditautkan dengan libdyno.so
dan gunakan fungsi yang baru saja kita definisikan di dalamnya.
#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;
}
Kompilasi sebagai berikut
g++ -Wall -g -pedantic -L. -ldyno DynoLib_main.cpp -o dyno_main
./dyno_main
Square 2989441
Anda juga dapat melihat biner utama menggunakan nm
. Berikut ini saya melihat apakah ada sesuatu dengan string square
di dalamnya yaitu simbol yang saya butuhkan dari libdyno.so
dengan cara apa pun yang dirujuk dalam biner saya.
nm dyno_runner |grep square
U _ZN10DynamicLib6squareEi
Jawabannya iya. Huruf besar U
artinya tidak terdefinisi tetapi ini adalah nama simbol untuk metode kuadrat kita di Kelas DynamicLib yang kita buat sebelumnya. Nama yang tampak aneh ini disebabkan oleh pengacauan nama yang merupakan topiknya sendiri.
Bagaimana saya tahu mana yang harus ditautkan secara statis seperti yang saya lakukan dengan file regular.o dan mana yang seharusnya ditautkan secara dinamis?
Anda tidak perlu tahu. Anda menentukan apa yang ingin Anda tautkan dan membiarkan kompiler (dan penghubung dll) melakukan pekerjaannya. Perhatikan -l
bendera nama perpustakaan dan -L
mengatakan itu di mana mencarinya. Ada tulisan yang layak tentang bagaimana kompiler menemukan sesuatu di sini
opsi Tautan gcc -L:Cara alternatif cara menentukan jalur ke pustaka dinamis
Atau lihat man ld
.
Untuk apa flag -L dan -l? Apa artinya menentukanmisalnya flag -lusb pada baris perintah?
Lihat tautan di atas. Ini dari man ld
..
-L searchdir
Tambahkan direktori pencarian jalur ke daftar jalur yang akan dicari oleh ld untuk perpustakaan arsip dan skrip kontrol ld. Anda dapat menggunakan opsi ini beberapa kali. Direktori dicari dalam urutan yang ditentukan pada baris perintah. Direktori yang ditentukan pada baris perintah dicari sebelum direktori default. Semua opsi -Lot berlaku untuk semua opsi -l, terlepas dari urutan munculnya opsi. Opsi -L tidak mempengaruhi cara ld mencari linkerscript kecuali opsi -T ditentukan.`
Jika Anda berhasil sampai di sini, ada baiknya mempelajari tentang linker yaitu ld. Ini memainkan pekerjaan penting dan merupakan sumber banyak kebingungan karena kebanyakan orang mulai berurusan dengan kompiler dan berpikir bahwa compiler == linker
dan ini tidak benar.