FreeBASIC マニュアルのトップに戻る

FreeBASIC ProPgStaticLibraries

目次→教本→プログラマーのための案内Static Libraries←オリジナル・サイト

静的ライブラリ 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

←リンク元に戻る プログラム開発関連に戻る

静的ライブラリは、実行可能ファイルをビルドするときに使うことができる、コンパイル済みコードです。

コンパイラが、実行可能ファイルを作るときに、基本のソースファイルは、最初に、オブジェクト・ファイルに変換されます。
そのとき、オブジェクト・ファイルは、実行可能ファイルを作るために、一緒に結合されます。
ソースコードをコンパイルするとき、必ずしもひとつの実行可能ファイルにする必要は、ありません。
代わりに、私たちは、オブジェクト・ファイル(ソースから、作られる)のすべてを、静的ライブラリと呼ばれる一つのファイルに、集めます。

ライブラリは、静的と呼ばれます。というのは、ライブラリが含んでいるオブジェクト・ファイルは、後に実行可能ファイルに結合されるとき、ライブラリの必要なすべてのコードのコピーが、実行可能ファイルに加えられるからです。
言い換えると、ライブラリを変更した場合は、そのオブジェクトを、実行可能ファイルに結合し直すために、再度、コンパイルする必要が有ります。

一度、ライブラリを作っておくと、私たちは、ライブラリが含むコードを、まるで直接私たちのプログラムでソースをコンパイルしているように、使うことができます。

静的ライブラリとの変数の交換/共有
静的ライブラリでは、ライブラリ・コードとモジュール・コードの両方で、CommonExtern キーワードを使って変数を直接共有できます。
その他、ライブラリ手続きにパラメータを(値または参照)渡したり、ライブラリ関数から変数を(値または参照)返すことで、間接的に共有ライブラリとデータ交換(値で)したり、データ共有(参照で)したりできます。


静的ライブラリの簡単な例
下は、これらの3個のファイルを使って、静的なライブラリを生成する、簡単な例です:

この簡単な事例で作成するライブラリは、ただ一つの関数を提供する、ただ一つのモジュールです:

'' mylib1.bas
'' 右のようにコンパイルしてください: fbc -lib mylib1.bas

'' 2つの数字を合計して、結果を返します
Public Function Add2( ByVal x As Integer, ByVal y As Integer ) As Integer
  Return( x + y )
End Function


コンパイル・オプション 下のように、ライブラリをコンパイルします:
fbc -lib mylib1.bas

注意:FbEdit を使う場合は、オプションのリストから「Library」を選択します。
 
-lib オプションを指定すると、コンパイラは、ソースコード mylib1.bas をとって、ソースコードを、オブジェクト・ファイル mylib1.o に入れます。次に、保存記録とも呼ばれる、ライブラリ・ファイル libmylib1.a にオブジェクト・ファイルを蓄えます。
一般に、ライブラリは、多くのモジュール(ソースファイル)を、それぞれ多くの関数とともに含めることができます。しかし、この簡単な例では、それぞれ1つだけです。

他のソースコードで、ライブラリを利用するために、ライブラリにいったい何があるかを、コンパイラに伝える手段が必要です。
このための方法として、ヘッダーファイルに、ライブラリへの宣言 (インタフェースとか、API と呼ばれます) を置きます。

'' mylib1.bi
#inclib "mylib1"
Declare Function Add2( ByVal x As Integer, ByVal y As Integer ) As Integer


ヘッダーは、コンパイルする必要ありません。
他のソース・ファイルに含めることができるように、ヘッダーは、ソースの形式です。
#inclib 命令文は、私たちが、最終的に実行可能を作るときに結合する必要がある、静的ライブラリの名前を、コンパイラに伝えます。

私たちのライブラリ (.a ファイル) と、ヘッダー (.bi ファイル) を、テスト・プログラムで、試すことができます:

'' mytest1.bas
'' 右のようにコンパイルしてください: fbc mytest1.bas
#include once "mylib1.bi"
Print Add2 (1,2)
Sleep


#include 命令文は、mylib.bi から、ソースコードを含めるように、コンパイラに伝えます。これは、まさしく、元のソースに、mylib.bi の内容をタイプしたかのようになります。
私たちが、インクルード・ファイルを書いた通りに、インクルードファイルは、ライブラリについて知る必要があるすべてを、コンパイラに伝えます。

これを、下のように、コンパイルします:
fbc mytest1.bas

そして、実行可能ファイル mytest を実行すると、下の結果が表示されるでしょう。

3


OOP 静的ライブラリの高度な例
以下は、これらの3つのファイルを使って OOP 静的ライブラリを作成する高度な例です:

上記と同様の方法でライブラリをコンパイルしてから、テスト・プログラムをコンパイルして実行します。

ライブラリのヘッダーファイル:
'' header file: 'varZstring.bi'

Type varZstring Extends ZString
    Public:
        Declare Constructor (ByRef z As Const ZString)
        Declare Operator Cast () ByRef As ZString
        Declare Operator Let (ByRef z As Const ZString)
        Declare Property allocated () As Integer
        Declare Destructor ()
    Private:
        Dim As ZString Ptr _p
        Dim As UInteger _allocated
End Type

Declare Operator Len (ByRef v As varZstring) As Integer  '' mandatory for the user code to call
                                                         ''    the overload Len operator and
                                                         ''    not the prebuilt-in Len operator
注: 各多重定義手続きも合わせて宣言するように、注意してください。ユーザー・コードでの使用が、事前に組み込まれた手続きと構文的に互換性がある場合、宣言がなくても必ずしもコンパイル・エラーが発生するわけではないからです。しかし、結果は明らかに期待どおりではありません。

ライブラリのソースファイル:

'' library module: 'varZstring.bas'

#include "varZstring.bi"

Constructor varZstring (ByRef z As Const ZString)
    If This._p <> 0 Then
        Deallocate(This._p)
    End If
    This._allocated = Len(z) + 1
    This._p = CAllocate(This._allocated, SizeOf(ZString))
    *This._p = z
End Constructor

Operator varZstring.Cast () ByRef As ZString
    Return *This._p
End Operator

Operator varZstring.Let (ByRef z As Const ZString)
    If This._allocated < Len(z) + 1 Then
    Deallocate(This._p)
    This._allocated = Len(z) + 1
    This._p = CAllocate(This._allocated, SizeOf(ZString))
  End If
  *This._p = z
End Operator

Property varZstring.allocated () As Integer
    Return This._allocated
End Property

Destructor varZstring ()
    Deallocate(This._p)
    This._p = 0
End Destructor

Operator Len (ByRef v As varZstring) As Integer
    Return Len(Type<String>(v))  '' found nothing better than this
End Operator                     ''     (or: 'Return Len(Str(v))')

テスト・プログラムファイル:

'' test program: 'varZstringTest.bas'

#include "varZstring.bi"  '' must contain also the overload Len operator declaration,
                          ''    otherwise the prebuilt-in Len operator is called and applied
                          ''    on the object variable (providing the length of its member data)
                       
#inclib "varZstring"      '' one can also put this line in the 'varZstring.bi' file
                          ''   (and not in this file), but it seems a bit crooked

Print "VARIABLE",,, "|     LEN|  SIZEOF|"
Print "------------------------------------------|--------|--------|"

Dim As varZstring v = "FreeBASIC"  '' adjusts memory allocation to minimum
Print "varZstring v:", "'" & v & "'",, "|"; Using "########|"; Len(v); v.allocated

Dim As ZString * 256 z
z = v
Print "Zstring    z:", "'" & z & "'",, "|"; Using "########|"; Len(z); SizeOf(z)

v = z & " & SourceForge"  '' only increases memory allocation if necessazy
Print "varZstring v:", "'" & v & "'", "|"; Using "########|"; Len(v); v.allocated

v = z & " & Wiki" '' only increases memory allocation if necessazy
Print "varZstring v:", "'" & v & "'", "|"; Using "########|"; Len(v); v.allocated

v.Constructor(v)  '' readjusts memory allocation to minimum
Print "varZstring v:", "'" & v & "'", "|"; Using "########|"; Len(v); v.allocated

Sleep

出力:
VARIABLE                                  |     LEN|  SIZEOF|
------------------------------------------|--------|--------|
varZstring v: 'FreeBASIC'                 |       9|      10|
Zstring    z: 'FreeBASIC'                 |       9|     256|
varZstring v: 'FreeBASIC & SourceForge'   |      23|      24|
varZstring v: 'FreeBASIC & Wiki'          |      16|      24|
varZstring v: 'FreeBASIC & Wiki'          |      16|      17|



ライブラリを作るとき、複数のソース・モジュールを使用できます。
そして、基本プログラムは、それぞれの必要なヘッダーを含めることで、複数のライブラリを使用できます。
ライブラリには、いくつものヘッダーを使用する、とても大きなものもあります。
非常に大きいプロジェクトでは、めったに変わらないいくつかのコード・モジュールを、ライブラリに作っておくと、コンパイル時間を、劇的に改善することができます。

ライブラリは、任意で、-g コマンドライン・オプションを指定することで、デバッグ情報を含めることができます。

ライブラリは、オプションとして、モジュール構築子、メインコード、モジュール解体子を含めることができます。
モジュール構築子、次にメインコードの順にライブラリのロード時に実行されます。モジュール解体子はライブラリのアンロード時に実行されます。

オブジェクトファイルは、したがってライブラリは、プラットホーム特定で、いくつかの場合、コンパイラのバージョンと、FreeBASIC ランタイム・ライブラリに、特定です。

参照:
プログラマーのための案内に戻る
←リンク元に戻る プログラム開発関連に戻る
ページ歴史:2021-10-04 09:45:03
日本語翻訳:WATANABE Makoto、原文著作者:JeffMarshall

ホームページのトップに戻る

表示-非営利-継承