今回共有するのは趣旨静的ライブラリと動的ライブラリの作成と使用方法を学び、静的ライブラリと動的ライブラリの違いを理解し、使用時にどう選択するかを知ることです。ここでは静的ライブラリと動的ライブラリの基盤となる形式やメモリレイアウトなどについては深く解説しません。興味がある方は、『プログラマーの自己修養——リンク・ロード・ライブラリ』という本をお勧めします。
1.ライブラリとは
ライブラリとは、既に書かれていて、成熟した、再利用可能なコードのことです。実際には、すべてのプログラムは多くの基本的な低レベルライブラリに依存しています。誰もがゼロからコードを書くわけにはいかないので、ライブラリの存在意義は非常に大きいのです。。
本質的に、ライブラリは実行可能コードのバイナリ形式であり、オペレーティングシステムによってメモリにロードされて実行されます。ライブラリには、静的ライブラリ(.a、.lib)と動的ライブラリ(.so、.dll)の2種類があります。
静的・動的とは、リンクを指します。プログラムをコンパイルして実行可能プログラムにする手順を振り返ってみましょう。
図:コンパイルのプロセス
2.静的ライブラリ
【静的ライブラリ】と呼ばれるのは、リンク段階で、アセンブルによって生成されたオブジェクトファイル.oと参照されたライブラリが一緒にリンクされ、実行可能ファイルにパッケージ化されるからです。そのため、対応するリンク方式は静的リンクと呼ばれます。
考えてみてください。静的ライブラリはアセンブルで生成されたオブジェクトファイルと一緒にリンクされて実行可能ファイルになります。つまり、静的ライブラリは.oファイルと形式が似ているはずです。実際、静的ライブラリは簡単にオブジェクトファイルの集合(.o/.objファイル)の集合、すなわち多くのオブジェクトファイルが圧縮・パッケージ化されて形成された1つのファイルです。静的ライブラリの特徴をまとめると次のとおりです。
- 静的ライブラリの関数ライブラリへのリンクはコンパイル時に完了します。
- プログラムは実行時に関数ライブラリとは無関係になり、移植が容易です。
- 関連するすべてのオブジェクトファイルと関連する関数ライブラリが1つの実行可能ファイルにリンクされるため、スペースとリソースを浪費します。
次に、簡単な四則演算のC++クラスを作成し、それを静的ライブラリとしてコンパイルして他の人に使ってもらうことにします。ヘッダーファイルは次のとおりです。
| StaticMath.hヘッダーファイル |
#pragma once
class StaticMath
{
public:
StaticMath(void);
~StaticMath(void);
static double add(double a, double b);//加法
static double sub(double a, double b);//减法
static double mul(double a, double b);//乘法
static double div(double a, double b);//除法
void print();
};
|
Linuxではarツール、WindowsのVSではlib.exeを使用して、オブジェクトファイルを圧縮して1つにまとめ、さらに検索や照会が容易になるように番号とインデックスを付けます。一般的に静的ライブラリを作成する手順は図のとおりです。ar図:静的ライブラリ作成のプロセスlib.exe2.1.Linuxでの静的ライブラリの作成と使用
2.1.1.Linuxの静的ライブラリ命名規則
2.1.Linuxでの静的ライブラリの作成と使用
2.1.2.静的ライブラリ(.a)の作成
上記の流れからわかるように、Linuxで静的ライブラリを作成するプロセスは次のとおりです。
- まず、コードファイルをオブジェクトファイル.o(StaticMath.o)にコンパイルします。
パラメータ-cを付けることに注意してください。付けないと実行可能ファイルに直接コンパイルされます。
- 次に、arツールを使用してオブジェクトファイルを.a静的ライブラリファイルにパッケージ化します。
g++ -c StaticMath.cpp
静的ライブラリの生成
規模の大きいプロジェクトでは、makefile(CMakeなどのプロジェクト管理ツール)を作成して静的ライブラリを生成します。複数のコマンドを入力するのは面倒だからです。
ar -crv libstaticmath.a StaticMath.o
2.1.3.静的ライブラリの使用libstaticmath.a。
上で作成した静的ライブラリを使用するテストコードを書きます。
テストコード:
Linuxで静的ライブラリを使用するには、コンパイル時に静的ライブラリの検索パス(-Lオプション)と静的ライブラリ名(libプレフィックスと.a拡張子は不要、-lオプション)を指定するだけです。
| - -L:リンクするライブラリが存在するディレクトリを指定します。 |
#include "StaticMath.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
double a = 10;
double b = 2;
cout << "a + b = " << StaticMath::add(a, b) << endl;
cout << "a - b = " << StaticMath::sub(a, b) << endl;
cout << "a * b = " << StaticMath::mul(a, b) << endl;
cout << "a / b = " << StaticMath::div(a, b) << endl;
StaticMath sm;
sm.print();
system("pause");
return 0;
}
|
- -l:リンク時に必要な動的ライブラリを指定します。コンパイラが動的ライブラリを検索する際、暗黙の命名規則があります。指定した名前の前にlibを付け、後ろに.aまたは.soを付けてライブラリ名を決定します。
# g++ TestStaticLibrary.cpp -L../StaticLibrary -lstaticmath
2.2.Windowsでの静的ライブラリの作成と使用
2.2.1.静的ライブラリ(.lib)の作成
2.2.Windowsでの静的ライブラリの作成と使用
- まず、コンパイラオプションを使用して
コードをコンパイルします(
)、"StaticMath.obj"という名前のオブジェクトファイルを作成します。/cのCl.exe- 次に、ライブラリマネージャーを使用してcl /c StaticMath.cppコードをリンクし(
)、静的ライブラリStaticMath.libを作成します。Lib.exeもちろん、通常はこの方法は使わず、VSのプロジェクト設定を使う方が便利です。Win32コンソールプログラムを作成する際に、静的ライブラリの種類をチェックし、プロジェクトの「プロパティパネル」→「構成プロパティ」→「全般」を開き、構成の種類で静的ライブラリを選択します。lib StaticMath.obj図:VS静的ライブラリのプロジェクトプロパティ設定
プロジェクトをビルドすると静的ライブラリが生成されます。
2.2.2.静的ライブラリの使用
テストコードはLinuxの場合と同じです。使用方法は3つあります。
方法1:
VSで静的ライブラリを使用する方法:
プロジェクトの「プロパティパネル」→「共通プロパティ」→「フレームワークと参照」→「参照の追加」で、「参照の追加」ダイアログが表示されます。「プロジェクト」タブには、現在のソリューション内の各プロジェクトと、参照できるすべてのライブラリが一覧表示されます。「プロジェクト」タブで、StaticLibraryを選択します。「OK」をクリックします。
StaticMath.h ヘッダーファイルのディレクトリを追加するには、インクルードディレクトリのパスを変更する必要があります。プロジェクトの「プロパティパネル」→「構成プロパティ」→「C/C++」→「全般」を開き、「追加のインクルードディレクトリ」のプロパティ値に、StaticMath.h ヘッダーファイルが存在するディレクトリのパスを入力するか、そのディレクトリを参照します。
コンパイルして実行すればOKです。
図:静的ライブラリのテスト結果(VS)
参照する静的ライブラリが同じソリューション内のサブプロジェクトではなく、サードパーティが提供する静的ライブラリのlibとヘッダーファイルを使用する場合、上記の方法では設定できません。残り2つの方法でも設定可能です。
方法2:
プロジェクトの「プロパティパネル」→「構成プロパティ」→「リンカー」→「コマンドライン」を開き、静的ライブラリの完全なパスを入力します。
方法3:
- 「プロパティパネル」→「構成プロパティ」→「リンカー」→「全般」で、「追加のライブラリディレクトリ」に静的ライブラリが存在するディレクトリを入力します。
「プロパティパネル」→「構成プロパティ」→「リンカー」→「入力」で、「追加の依存ファイル」に静的ライブラリ名StaticLibrary.libを入力します。
3.動的ライブラリ
上記の説明から、静的ライブラリは使いやすく理解しやすく、コード再利用の目的も達成できることがわかりました。では、なぜ動的ライブラリも必要なのか?
3.動的ライブラリ
なぜ動的ライブラリが必要なのか、それは実は静的ライブラリの特徴によるものです。
3.1.なぜ動的ライブラリも必要なのか?
もう1つの問題は、静的ライブラリがプログラムの更新、展開、リリースにも問題をもたらすことです。静的ライブラリliba.libが更新された場合、それを使用するすべてのアプリケーションを再コンパイルし、ユーザーに再リリースする必要があります(プレイヤーにとっては、ごく小さな変更であっても、プログラム全体を再ダウンロードすることになり、
全量更新
動的ライブラリはプログラムのコンパイル時にオブジェクトコードにリンクされず、プログラムの実行時にロードされます。異なるアプリケーションが同じライブラリを呼び出す場合、メモリ内にその共有ライブラリのインスタンスは1つだけで済みます。)。
これによりスペースの浪費の問題を回避できます。動的ライブラリはプログラムの実行時にロードされるため、静的ライブラリがプログラムの更新、展開、リリースに伴う問題も解決します。ユーザーは動的ライブラリを更新するだけでよいのです。増分更新動的ライブラリの特徴をまとめると次のとおりです。- 動的ライブラリは、一部のライブラリ関数のリンクとロードをプログラムの実行時まで延期します。。
- プロセス間でのリソース共有を実現できます。(そのため、動的ライブラリは共有ライブラリとも呼ばれます)
- 一部のプログラムのアップグレードが簡単になります。
- リンクとロードを完全にプログラマーがプログラムコード内で制御することも可能です(
明示的呼び出し
WindowsとLinuxでは実行ファイルの形式が異なるため、動的ライブラリを作成する際にはいくつかの違いがあります。Windowsシステムでは実行ファイルの形式はPE形式であり、動的ライブラリには)。
WindowsとLinuxでは実行ファイルの形式が異なり、ダイナミックライブラリを作成する際にいくつかの違いがあります。
- Windowsシステムでの実行ファイル形式はPE形式であり、ダイナミックライブラリには一つが必要です。DllMain関数は初期化の入口となる。通常、エクスポート関数の宣言には_declspec(dllexport)が必要である。キーワード。
- Linuxでgccコンパイルされた実行ファイルはデフォルトでELF形式である。初期化エントリが不要で、関数の特別な宣言も不要である。作成が比較的便利である。
静的ライブラリの作成と異なり、パッケージツール(ar、lib.exe)は不要で、コンパイラのみで動的ライブラリを作成できる。
3.2.Linuxでの動的ライブラリの作成と使用
3.2.1.linux動的ライブラリの命名規則
動的リンクライブラリの名前形式はlibxxx.soで、接頭辞はlib、接尾辞は".so"である。
実にするライブラリファイルに対して、各共有ライブラリには特別な名前「soname」がある。プログラム起動後、プログラムはこの名前を通じて動的ローダーにどの共有ライブラリをロードするかを伝える。
ファイルシステムでは、sonameは実際の動的ライブラリへのリンクにすぎない。動的ライブラリにとって、各ライブラリにはコンパイラが使う別の名前が実際にあり、それは実際のライブラリイメージファイルへのリンクファイル(lib+soname+.so)である。
3.2.2.動的ライブラリ(.so)の作成
四則演算の動的ライブラリコードを作成する:
| DynamicMath.hヘッダーファイル |
#pragma once
class DynamicMath
{
public:
DynamicMath(void);
~DynamicMath(void);
static double add(double a, double b);//加法
static double sub(double a, double b);//减法
static double mul(double a, double b);//乘法
static double div(double a, double b);//除法
void print();
};
|
- まず、オブジェクトファイルを生成する。このときコンパイラオプション-fpicを追加する。
g++ -fPIC -c DynamicMath.cpp
-fPIC アドレスに依存しないコンパイルプログラム(pic、position independent code)を作成する。複数のアプリケーション間で共有できるようにするためである。
- 次に、動的ライブラリを生成する。このときリンカーオプション-sharedを追加する。
g++ -shared -o libdynmath.so DynamicMath.o
-sharedは動的リンクライブラリの生成を指定する。
実は上記2つのステップは1つのコマンドにまとめることができる:
g++ -fPIC -shared -o libdynmath.so DynamicMath.cpp
3.2.3.動的ライブラリの使用
動的ライブラリを使用するテストコードを作成する:
| テストコード: |
#include "../DynamicLibrary/DynamicMath.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
double a = 10;
double b = 2;
cout << "a + b = " << DynamicMath::add(a, b) << endl;
cout << "a - b = " << DynamicMath::sub(a, b) << endl;
cout << "a * b = " << DynamicMath::mul(a, b) << endl;
cout << "a / b = " << DynamicMath::div(a, b) << endl;
DynamicMath dyn;
dyn.print();
return 0;
}
|
動的ライブラリを参照して実行可能ファイルにコンパイルする(静的ライブラリと同じ方法):
g++ TestDynamicLibrary.cpp -L../DynamicLibrary -ldynmath
そして実行:./a.out、なんとエラーが発生した!!!
皆さんは、動的ライブラリがテストプログラムと同じディレクトリにないからだと思うかもしれない。検証してみよう:
やはりエラーが発生した!!!では、実行時に共有ライブラリファイルをどのように特定するのだろうか?
1) システムが実行可能コードをロードするとき、依存するライブラリの名前はわかるが、絶対パスも必要である。このときシステムの動的ローダー(dynamic linker/loader)が必要となる。
2) elf形式の実行可能プログラムでは、ld-linux.so*がその処理を実行する。これは、elfファイルのDT_RPATHセグメント、環境変数LD_LIBRARY_PATH、/etc/ld.so.cacheファイルリスト、/lib/、/usr/libディレクトリの順に検索し、ライブラリファイルを見つけた後にそれをメモリへロードする。
システムがそれを見つけられるようにする方法:
- /libまたは/usr/libの下にインストールすれば、ldはデフォルトで見つけることができ、追加の操作は不要である。
- 他のディレクトリにインストールする場合は、/etc/ld.so.cacheファイルに追加する必要がある。手順は以下の通り:
-- /etc/ld.so.confファイルを編集し、ライブラリファイルがあるディレクトリのパスを追加する
-- ldconfigを実行する。このコマンドは/etc/ld.so.cacheファイルを再構築する
作成した動的ライブラリを/usr/libの下にコピーし、テストプログラムを実行する。
3.3.Windowsでの動的ライブラリの作成と使用
3.3.1.動的ライブラリ(.dll)の作成
Linuxと比べて、Windowsシステムでの動的ライブラリの作成は少し面倒である。まず、DllMain関数が初期化の入口となる必要がある(win32コンソールプログラム作成時に、DLLタイプをチェックするとこのファイルが自動生成される):
| dllmain.cppエントリファイル |
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
|
通常、エクスポート関数の宣言には_declspec(dllexport)キーワードが必要である:
| DynamicMath.hヘッダーファイル |
#pragma once
class DynamicMath
{
public:
__declspec(dllexport) DynamicMath(void);
__declspec(dllexport) ~DynamicMath(void);
static __declspec(dllexport) double add(double a, double b);//加法
static __declspec(dllexport) double sub(double a, double b);//减法
static __declspec(dllexport) double mul(double a, double b);//乘法
static __declspec(dllexport) double div(double a, double b);//除法
__declspec(dllexport) void print();
};
|
動的ライブラリを生成するにはプロジェクトのプロパティを設定する必要がある。プロジェクトの「プロパティパネル」--「構成プロパティ」--「全般」を開き、構成タイプで動的ライブラリを選択する。
図:VS動的ライブラリプロジェクトのプロパティ設定
プロジェクトをビルドすると動的ライブラリが生成される。
3.3.2.動的ライブラリの使用
win32コンソールテストプログラムを作成する:
| TestDynamicLibrary.cppテストプログラム |
#include "stdafx.h"
#include "DynamicMath.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
double a = 10;
double b = 2;
cout << "a + b = " << DynamicMath::add(a, b) << endl;
cout << "a - b = " << DynamicMath::sub(a, b) << endl;
cout << "a * b = " << DynamicMath::mul(a, b) << endl;
cout << "a / b = " << DynamicMath::div(a, b) << endl;
DynamicMath dyn;
dyn.print();
system("pause");
return 0;
}
|
方法1:
プロジェクトの「プロパティパネル」--「共通プロパティ」--「フレームワークと参照」--「参照の追加」で「参照の追加」ダイアログが表示される。「プロジェクト」タブには、現在のソリューション内の各プロジェクトと参照可能なすべてのライブラリが一覧表示される。「プロジェクト」タブでDynamicLibraryを選択し、「OK」をクリックする。
- DynamicMath.hヘッダーファイルのディレクトリを追加するには、インクルードディレクトリのパスを変更する必要がある。プロジェクトの「プロパティパネル」--「構成プロパティ」--「C/C++」--「全般」を開き、「追加のインクルードディレクトリ」のプロパティ値にDynamicMath.hヘッダーファイルがあるディレクトリのパスを入力するか、そのディレクトリを参照する。
コンパイル・実行OK。
図:動的ライブラリのテスト結果(VS)
方法2:
- 「プロパティパネル」--「構成プロパティ」--「リンカー」--「全般」の「追加のライブラリディレクトリ」に動的ライブラリがあるディレクトリを入力する;
「プロパティパネル」--「構成プロパティ」--「リンカー」--「入力」の「追加の依存ファイル」に動的ライブラリをコンパイルして生成されたDynamicLibrary.libを入力する。
ここで疑問があるかもしれない。動的ライブラリなのにDynamicLibrary.libファイルもあるのか?つまり、静的リンクライブラリでも動的リンクライブラリでも、最終的にlibファイルがある。では両者の違いは何か?実は、両者は全く異なるものである。
StaticLibrary.libのサイズは190KB、DynamicLibrary.libのサイズは3KBである。静的ライブラリに対応するlibファイルは静的ライブラリ、動的ライブラリに対応するlibファイルは【インポートライブラリ】。実際、静的ライブラリ自体には実行コードやシンボルテーブルなどが含まれているが、インポートライブラリについては、その実際の実行コードは動的ライブラリ内にあり、インポートライブラリはアドレスシンボルテーブルなどを含み、プログラムが対応する関数の基本的なアドレス情報を見つけられるようにするだけである。。
4.動的ライブラリの明示的呼び出し
上記で紹介した動的ライブラリの使用方法は静的ライブラリと同様で、暗黙的呼び出しに属し、コンパイル時に対応するライブラリと検索パスを指定する。実は、動的ライブラリは明示的に呼び出すこともできる。【C言語中】動的ライブラリを明示的に呼び出すのは簡単である!
4.1.Linuxでの動的ライブラリの明示的呼び出し
#include <dlfcn.h>、以下のインターフェースが提供される:
- void * dlopen( const char * pathname, int mode ):指定されたモードで指定された動的リンクライブラリファイルを開き、呼び出しプロセスにハンドルを返す関数である。
- void* dlsym(void* handle,const char* symbol):dlsymは動的リンクライブラリの操作ハンドル(pHandle)とシンボル(symbol)に基づき、シンボルに対応するアドレスを返す。この関数を使うと関数アドレスだけでなく変数アドレスも取得できる。
- int dlclose(void *handle):dlcloseは指定されたハンドルの動的リンクライブラリを閉じるために使われる。この動的リンクライブラリの使用カウントが0になったときだけ、実際にシステムによってアンロードされる。
- const char *dlerror(void):動的リンクライブラリ操作関数の実行が失敗したとき、dlerrorはエラー情報を返す。戻り値がNULLの場合は操作関数の実行が成功したことを示す。
4.2.Windowsでの動的ライブラリの明示的呼び出し
アプリケーションは実行時にDLLを明示的にロードするために関数呼び出しを行う必要がある。DLLに明示的にリンクするには、アプリケーションは次のことを行う必要がある:
- 呼び出しLoadLibrary(または類似の関数)でDLLをロードし、モジュールハンドルを取得する。
- 呼び出しGetProcAddressを行い、アプリケーションが呼び出す各エクスポート関数への関数ポインタを取得する。アプリケーションはポインタを介してDLLの関数を呼び出すため、コンパイラは外部参照を生成せず、インポートライブラリとのリンクは不要である。
- DLLの使用が終わったら、 を呼び出すFreeLibrary。
4.3.C++動的ライブラリを明示的に呼び出す際の注意点
C++の場合、状況は少し複雑である。C++動的ライブラリを明示的にロードすることの難しさは、一部はC++のname mangling(名前マングリング)が原因であり、;もう一部は、適切な(方法)がAPIクラスをロードするために提供されていないことによる。、C++では、ライブラリ内のクラスを使用する必要があるかもしれない。その場合、そのクラスのインスタンスを作成する必要があり、これは簡単ではない。
name manglingextern "C" で解決できる。C++にはCバインディングの関数を宣言するための特定のキーワードがある:extern "C"。extern "C" で宣言された関数は、C関数と同様に、関数名をシンボル名として使用する。したがって、非メンバー関数のみが extern "C" として宣言でき、オーバーロードもできない。制限は多いが、extern "C" 関数はC関数のように dlopen で動的にロードできるため、非常に有用である。extern "C" 限定子を付けても、関数内でC++コードを使用できないという意味ではなく、逆に、それは依然として完全なC++関数であり、あらゆるC++機能やさまざまな型のパラメータを使用できる。
また、C++動的ライブラリからクラスを取得する方法について、関連記事をいくつか添付するが、これをお勧めするわけではない:
- 「LoadLibraryでDLL内のClassを呼び出す」:http://www.cppblog.com/codejie/archive/2009/09/24/97141.html
- 《C++ dlopen mini HOWTO》:http://blog.csdn.net/denny_233/article/details/7255673
「明示的」にC++動的ライブラリ内のClassを使用することは非常に煩雑で危険なことである。したがって、「暗黙的」を使えるなら「明示的」は使わないこと。静的を使えるなら動的は使わないこと。
5.付録:Linuxでのライブラリ関連コマンド
5.1.g++(gcc)コンパイルオプション
-shared :動的リンクライブラリの生成を指定する。
-static :静的リンクライブラリの生成を指定する。
-fPIC :位置独立のコードとしてコンパイルすることを示し、共有ライブラリのコンパイルに使用する。オブジェクトファイルは位置独立コードとして作成する必要がある。概念のには、実行プログラムがそれらをロードするとき、実行プログラムのメモリ内のどこにでも配置できることを意味する。
- -L. :リンクするライブラリが存在するディレクトリを示す。
- -l:リンク時に必要な動的ライブラリを指定する。コンパイラが動的リンクライブラリを検索する際には暗黙の命名規則があり、指定された名前の前にlibを付け、後ろに.a/.soを付けてライブラリ名を決定する。
- -Wall :すべての警告情報を生成する。
- -ggdb :このオプションは、gdbで使用可能なデバッグ情報を可能な限り生成する。
- -g :コンパイラはコンパイル時にデバッグ情報を生成する。
- -c :プリプロセス、コンパイル、アセンブルのみを有効にする。つまり、プログラムをオブジェクトファイル(.oファイル)にする。
- -Wl,options :パラメータ(options)をリンカldに渡す。options内にカンマがある場合は、optionsを複数のオプションに分割してからリンカに渡す。
5.2.nmコマンド
ライブラリにどのような関数があるかを確認する必要がある場合がある。nmコマンドライブラリ内の関連するすべてのシンボルを表示できる。ライブラリは静的でも動的でもよい。nmが列挙するシンボルは多数あるが、一般的なものは3種類ある:
- ライブラリ内で呼び出されるが、ライブラリ内では定義されていないもの(他のライブラリのサポートが必要であることを示す)。Uで表す。
- ライブラリ内で定義された関数。Tで表す。これが最も一般的である。
- いわゆる弱いシンボル。ライブラリ内で定義されているが、他のライブラリ内の同名のシンボルによって上書きされる可能性がある。Wで表す。
$nm libhello.h
5.3.lddコマンド
lddこのコマンドは、実行可能プログラムが依存する共有ライブラリを確認できる。例えば、我々が作成した四則演算の動的ライブラリは以下のライブラリに依存している:
6.まとめ
両者の違いは、コードがロードされるタイミングが異なることにある。。
- 静的ライブラリはプログラムのコンパイル時にオブジェクトコードにリンクされ、プログラム実行時にはその静的ライブラリは不要になる。そのためサイズが大きくなる。。
- 動的ライブラリはプログラムのコンパイル時にはオブジェクトコードにリンクされず、プログラム実行時にロードされる。そのため、プログラム実行時には動的ライブラリが存在している必要がある。そのためコードサイズは小さくなる。。
動的ライブラリの利点は、異なるアプリケーションが同じライブラリを呼び出す場合、メモリ内にその共有ライブラリのインスタンスが1つだけで済むことである。利点がある一方で、問題も発生する!例えば、古典的なDLL Hell問題である。動的ライブラリ管理の問題を回避する方法については、関連資料を自分で調べるとよい。
7.関連チュートリアル
C++ チュートリアル:http://www.w3cschool.cc/cplusplus/cpp-tutorial.html
作者:吴秦
出典:http://www.cnblogs.com/skynet/
![clip_image002[4] clip_image002[4]](../wp-content/uploads/2015/05/16201601-66b55a2f0ec74c5b8a773a0e1904e812.png.webp)
![clip_image004[4] clip_image004[4]](../wp-content/uploads/2015/05/16201602-e0b2900a915d4dce8b4af5153c8b2d72.png.webp)
![clip_image006[4] clip_image006[4]](../wp-content/uploads/2015/05/16201604-713c3a4a83aa4c17868a16f13b49027b.jpg.webp)
![clip_image008[4] clip_image008[4]](../wp-content/uploads/2015/05/16201604-ae57e89353c74265a0f1d26e89ffdbd5.jpg.webp)
![clip_image010[4] clip_image010[4]](/wp-content/uploads/2015/05/16201605-6a3acac10b40402ea99343ad092f0061.jpg.webp)
![clip_image012[4] clip_image012[4]](../wp-content/uploads/2015/05/16201607-fed082fd8a134770b24c2b4569ad4405.jpg.webp)
![clip_image014[4] clip_image014[4]](../wp-content/uploads/2015/05/16201609-9be107869b604f53bc08653fe28bfbad.jpg.webp)
![clip_image015[4] clip_image015[4]](../wp-content/uploads/2015/05/16201610-8630c9a19cae4143bffacd255367ffbb.png.webp)
![clip_image017[4] clip_image017[4]](/wp-content/uploads/2015/05/16201610-2bde8b094f5a4603848c574f1f228144.jpg.webp)
![clip_image019[4] clip_image019[4]](../wp-content/uploads/2015/05/16201612-3af709f047ca4964898f3ce29680093c.jpg.webp)
![clip_image021[4] clip_image021[4]](../wp-content/uploads/2015/05/16201613-1320ec57feb24583a6b1294421c323b8.png.webp)
![clip_image023[4] clip_image023[4]](../wp-content/uploads/2015/05/16201613-110ca9e0fd684281b3ee6d9bd9bebd78.png.webp)
![clip_image025[4] clip_image025[4]](../wp-content/uploads/2015/05/16201614-02f4340b15664f8a83282fb9a27ca3e5.jpg.webp)
![clip_image027[4] clip_image027[4]](../wp-content/uploads/2015/05/16201616-45dcaece0519453c96dfd1972295cd92.jpg.webp)
![clip_image029[4] clip_image029[4]](../wp-content/uploads/2015/05/16201617-93f234207a9947a6a1caadd8acd9ead7.jpg.webp)
![clip_image031[4] clip_image031[4]](../wp-content/uploads/2015/05/16201618-a32a866f00c84a74893fa2181fa27b11.jpg.webp)
![clip_image033[4] clip_image033[4]](/wp-content/uploads/2015/05/16201619-f190d6dd94ee48e0883bb5d5bbe4e66a.jpg.webp)
![clip_image035[4] clip_image035[4]](../wp-content/uploads/2015/05/16201623-914ff83612a4470fa59c2bc729053c6b.jpg.webp)
![clip_image037[4] clip_image037[4]](../wp-content/uploads/2015/05/16201624-9cfecaf931ba4f4d96d6cf7cac3ac40e.jpg.webp)
![clip_image038[4] clip_image038[4]](../wp-content/uploads/2015/05/16201626-29defaed72cf4a91b7c83f6bd0fecf53.png.webp)
![clip_image040[4] clip_image040[4]](/wp-content/uploads/2015/05/16201626-98727f19e0d14d43942771bac7e24238.jpg.webp)
![clip_image042[4] clip_image042[4]](../wp-content/uploads/2015/05/16201628-425bd512f3bf4b51b121bdb59604bc5e.jpg.webp)
![clip_image044[4] clip_image044[4]](../wp-content/uploads/2015/05/16201631-f72543fd66ba4593996f864a7fb6f92a.jpg.webp)
![clip_image046[4] clip_image046[4]](../wp-content/uploads/2015/05/16201633-aebe0e8017354a9b93644043b9d013c6.jpg.webp)