#pragma twice

KAB-studio > プログラミング > #pragma twice > 308 Version 15.08 スタティックリンクライブラリの仕組み

#pragma twice 308 Version 15.08 スタティックリンクライブラリの仕組み

前のページへ 表紙・目次へ 次のページへ

 Version 15.08
スタティックリンクライブラリの仕組み

前回はスタティックリンクライブラリをとりあえず作って使ってみまし

かなり駆け足だったね
ということで今回はもう一度ゆっくり見てみます。まず、作る方から。
プロジェクト SLLTest っていうのを作りました。ソースファイルは2つ

// Sub.cpp

#include <Windows.h>
#include "Sub.h"

void Test()
{
    OutputDebugString( "テスト\n" );
}


// Sub.h

void Test();

関数ひとつだけだよね
さて、これをビルドすると

SLLTest.lib

というファイルが作られます
ホントだ、できてる
これは【ライブラリファイル】といって、スタティックリンクライブラリ
の本体です
え、これが!?
この中に Test() 関数そのものが入っています。だから、たとえば
スタティックリンクライブラリをインターネットで配布するとしたら、この
ファイルは必ず入れなきゃいけないわけです
この中に本体があるんだもんね……ん? 今の言い方だと、他に必要な
ファイルがあるの?
もちろん、ヘッダーファイルが必要でしょ
あ、 Sub.h !
そう。スタティックリンクライブラリはオブジェクトファイルみたいなも
のだから
リンクのためのものであって、コンパイルするためには関数の宣言がな
きゃってことね
そういうこと。もちろん、最悪の場合ヘッダーファイルはなくてもいいん
だけど
そりゃ、関数宣言書いちゃえばいいだけだからそうなのかもしれないけ
ど、そもそもそういう場合って関数のどんな関数が入ってるのかすら分から
ないよーな……
さて、次は使う側の話。使う方は、これまでの BuildTest プロジェクト
を使用します
? じゃあスタティックリンクライブラリってあれだけなの?
そう、あれだけ。特に難しく考えなくても使えるのが
スタティックリンクライブラリ
そうなんだ……
さて、使う側ですが、その前に、 SLLTest フォルダは

D:\Program\SLLTest

というパスになっているとします
前回のおことわりね
さて、使う側のソースファイルは1つ、以下のようになっています

// Main.cpp
#include <Windows.h>

#include "Sub.h"

int WINAPI WinMain
    ( HINSTANCE p_hInstance
    , HINSTANCE p_hPrevInstance
    , LPSTR p_pchCmdLine
    , int p_iCmdShow
    )
{
    Test();
    return 0;
}

さっきの関数を呼び出すってだけね
まず、このプログラムをコンパイルできるようにするため、 Test() 関数
が宣言されている Sub.h ヘッダーファイルをインクルードできるようにしま

まずはそこからね
まず、 BuildTest のメニューの【プロジェクト】-【設定】ダイアログを
開いてください
例の設定ダイアログね
その中の【C/C++】タブの【プリプロセッサ】ページの、
【インクルードファイルのパス】に

D:\Program\SLLTest

と書いてください
さっきの、プロジェクトのフォルダね
もっと正確に言うと、 Sub.h が置いてあるフォルダ
そか、ヘッダーファイルを見に行くんだから、そのフォルダを指定しな
きゃいけないんだ
そういうこと。この状態ならコンパイルは通ります
え? これだけでいいの?
そう、こういうふうにフォルダを指定することで、インクルード時に
ファイルを探してくれるから
ほほう。んじゃビルド

--------------------構成: BuildTest - Win32 Debug--------------------
コンパイル中...
Main.cpp
リンク中...
Main.obj : error LNK2001: 
外部シンボル ""void __cdecl Test(void)" (?Test@@YAXXZ)" は未解決です
Debug/BuildTest.exe : fatal error LNK1120: 外部参照 1 が未解決です。
link.exe の実行エラー

BuildTest.exe - エラー 2、警告 0

あ、コンパイル通ったけどリンクエラーになった。そりゃそっか、関数本
体はないんだもんね
今はまだインクルードファイルを参照してるだけだからね。この辺も、
スタティックリンクライブラリがオブジェクトファイルと同じってところ
なるほどね〜
ちなみに、ヘッダーファイルの参照方法はもうひとつあります。
Version 15.05 ( No.305 ) で教えたでしょ
あ! オプションで設定するのだ!
そう、【ツール】−【オプション】ダイアログの【ディレクトリ】−
【インクルードファイル】に

D:\Program\SLLTest

を追加しても同じことができます
どう違うの?
設定の方はプロジェクト単位だから、複数のプロジェクトで使う場合には
それぞれのプロジェクトで設定しなきゃいけない、けど
オプションの方は Visual C++ の設定だから、プロジェクト全部で使える
ってことね。でもそれはそれでまずくない?
だね、だから本当にほとんどのプロジェクトで使うようなライブラリだけ
かな、オプションの方がいいのは
ま、こういう方法もあるってことね
さて、話を戻して、今度はリンクエラーを取り除きます。先ほどと同じ
く、 BuildTest のメニューの【プロジェクト】-【設定】ダイアログを開い

この設定ダイアログっていろんな使い道があるのね……
まぁほとんどの設定がここでできるからね。【リンク】タブの
【インプット】の【追加ライブラリのパス】に

D:\Program\SLLTest\Debug

を書いて
これは、 SLLTest.lib を置いてあるフォルダ、ってこと?
そういうこと。ヘッダーファイルと同じで、フォルダを指定することでそ
のフォルダにファイルを探しにいってくれます
同じねー
ただ、ヘッダーファイルと違うのは、ヘッダーファイルは #include で
インクルードしたけど、ライブラリファイルは?
あ、そういえば……ソースファイルの方ではそんな感じなかったけど
そう、どのライブラリファイルを使うか、っていうのは設定の方で指定し
ます。同じく【インプット】の、【オブジェクト/ライブラリ モジュール】


SLLTest.lib

を半角スペースを入れて追加して
っていうと……

kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib
 advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib
 odbc32.lib odbccp32.lib SLLTest.lib

あ、実際には一行になるけど、こんな感じ?
そう、そんな感じ
ってゆーか、なんでこんなにいっぱいあるの?
これ全部、 API を使うための lib ファイル
これ全部スタティックリンクライブラリ!?
ううん、違うよ
へ、違うの?
ほとんどが DLL の。 DLL もライブラリファイルを使うから
あ、そうなんだ……それでも、これだけのが必要なんだね……
さて、これで使うライブラリファイルを指定できたから
ん、ビルドして実行! うん、〈テスト〉って出力された
これでスタティックリンクライブラリが使えました。まとめる


・インクルードファイルのあるフォルダを指定する。
・ライブラリファイルのあるフォルダを指定する。
・ライブラリファイルを指定する。

この3つね、意外と簡単かも……あ! そういえば、
ライブラリファイルも、インクルードファイルみたいに
オプションで指定できないの?
できるよ。同じように【ライブラリ ファイル】っていう項目があるから
そこでライブラリファイルのあるフォルダを指定すれば同じようにできま

おー
それともうひとつ、ヘッダーファイルもライブラリファイルも、フォルダ
の指定が必要ない方法があります
え、そんなこともできるの? どうやって?
 Sub.h と SLLTest.lib を SLLTest フォルダにコピーしちゃうこと
……あー、ファイルのコピーね…… Sub.h はともかく、 SLLTest.lib は
ビルドするたびに更新が必要じゃない
そうなんだけどね……。それと最後に、ライブラリファイルも、実は
インクルードファイルみたいにプリプロセッサで指定することができます
 #include みたいに?
そう、こんな感じに

// Main.cpp
#include <Windows.h>

#include "Sub.h"

#pragma comment( lib, "SLLTest.lib" )

int WINAPI WinMain
// 以下略

あ、 #pragma だ
こういう形式でも指定できます。実は MFC ではこの方法を採用してい
て、 MFC のプロジェクトで、ライブラリファイルを全然指定していないの
はこういう理由なんです
ってことは、 MFC でもなんでも、ライブラリファイルは必要ってこ
と?
そういうこと。 API を使う限り、ライブラリファイルからは逃れられな
いってことで

/*
    Preview Next Story!
*/
意外と簡単だったわー
そんな火美ちゃんに次回から超ハードな問題を!
それってもしかして……もしかする?
というわけで次回
< Version 15.09 DLLを作る! >
につづく!
いよいよ DLL !
 DLL キター!! てかそんなに超ハードなの?
ま、次回はちょっと簡単め、だけどね
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。