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

FreeBASIC ProPgSharedLibraries-DOS

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

共有ライブラリ(DLL)-DOS 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

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

共有ライブラリーは、後で実行ファイルを実行するときにロードして使用できるコンパイル済みコードです。

記述:
DOS は共有ライブラリ (ダイナミックリンクライブラリ) をサポートしていますが、Linux や Windows と比較していくつかの制限があります。
DOS ターゲットは、DJ の GNU プログラミング・プラットフォーム (DJGPP) の dxe3gen ユーティリティを使って DXE ファイル (共有ライブラリ) を作成します。

サポート
制限
DXE3GEN
dxe3gen は動的にロード可能なコード (DXE) を含むファイルを作成できるユーティリティです。
DXEは、「動的にロード可能な実行可能モジュール」の同義語として使われます。dxe3gen を参照してください。

dxe3gen では、その DXE_LD_LIBRARY_PATH が設定されることを想定しています。環境変数がまだ設定されていない場合、fbc は dxe3gen を呼び出す前に変数を fbc のライブラリパスに設定します。

fbc のスタンドアロンセットアップでは、dxe3gen'ld' リンカを起動して実行ファイルを生成し、それを .DXE ファイルに変換するので、カスタム・リンカ・スクリプト dxe.ld が fbc のライブラリパスに存在することが期待されます。

実行時の動的読み込みを使用した共有ライブラリ
この最初の例では、DXE に d1.bas のソースを、テストに m1.bas のソースを使用します。
この例は、Linux や Windows でも変更なく動作しますが、例のソースには相違点を記載しています。
$ fbc d1.bas は、DOS上で、d1.dxe 動的リンクライブラリと libd1_il.a インポートライブラリを生成します。
$ fbc m1.bas は、DOS上で、m1.exe 実行可能ファイルを生成します。

ライブラリの読み込みと関数ポインターの読み込みは、実行時にユーザーが手動で処理します。

'' d1.bas - dynamic link library

'' tell fbc to build a dynamic link library
#cmdline "-dll"

'' on DOS:
''   - creates d1.dxe (dynamic link library)
''   - creates libd1_il.a (import library)
'' on Windows:
''   - creates d1.dll (dynamic link library)
''   - creates libd1.dll.a (import library)
''   - either d1.dll or libd1.dll.a must be found to link an
''     executable using d1.dll
''   - d1.dll must be found to load and run an executable
''     using d1.dll
'' on Linux:
''   - creates libd1.so (dynamic link library)
''   - libd1.so must be found to load and run an executable
''     using libd1.do
''   - $ LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./executable

Sub proc_d1( ByRef fromproc As Const String ) Export
    Print __FILE__ & " : " & __FUNCTION__ & " @ " & _
        Hex(ProcPtr(proc_d1),SizeOf(Any Ptr)*2) & _
        " called from: " & fromproc
End Sub


'' m1.bas - dynamically load "D1" library and symbol "PROC_D1" at run time
''
'' library loading and symbol pointers are managed
'' manually by the user.

#define NULL 0

'' variable to hold a handle to the loaded dynamic link libray
Dim library As Any Ptr

'' prototype the function pointer
Type PROC_D1_PTR As Sub( ByRef from As Const String )

'' variable to hold a pointer to the sub/function in the dll
Dim proc_d1 As PROC_D1_PTR

'' some differences in naming between DOS and other targets,
'' so assign the names to some constants so the build process
'' can work on DOS and other targets:
#ifdef __FB_DOS__
    Const D1_DLL_NAME = "d1.dxe"
    Const PROC_D1_NAME = "_PROC_D1"
#else
    Const D1_DLL_NAME = "d1"
    Const PROC_D1_NAME = "PROC_D1"
#endif

'' try to load in the libray
library = DyLibLoad( D1_DLL_NAME )

If( library = NULL ) Then
    Print "unable to load library " + D1_DLL_NAME
    End 1
End If

'' get a function pointer to the procedure defined in the DXE
proc_d1 = DyLibSymbol( library, PROC_D1_NAME )
If( proc_d1 = NULL ) Then
    Print "unable to load symbol " + PROC_D1_NAME
    End 1
End If

'' call the loaded procedure
proc_d1( __FILE__ & " : " & __FUNCTION__ )

'' release the library
DyLibFree( library )


インポート ライブラリを使用した共有ライブラリ
この例では、DXE に d1.bas ソース(上記)を使用し、テストに下記の m2.bas を使用します。
この例は、Linux や Windows でも変更なく動作しますが、例のソースに相違点を記載しています。
$ fbc d1.bas (上から)は、DOS上で、d1.dxe 動的リンクライブラリと libd1_il.a インポートライブラリを生成します。
$ fbc m2.bas は、DOS上で、m2.exe 実行可能ファイルを生成します。

ライブラリの読み込みと関数のエクスポートは、実行可能ローダーとランタイム起動コードによって自動的に処理されます。
インクルードファイル d1.bi は厳密には必要ありませんが、複数のモジュール間での使用法の不一致がないように、関数が宣言される単一の場所を用意することを推奨します。

'' d1.bi - include file for d1.bas declarations
#pragma once
Declare Sub proc_d1( ByRef from As Const String )


'' m2.bas - link to import library

'' use an import library for d1.dxe/d1.dll/d1.so
''
'' library loading and symbol pointers are managed
'' automatically by the operating system and/or
'' runtime start-up code.

'' import libraries are named differently on
'' DOS compared to other targets.  Or in case of
'' at least win/linux not actually needed.  On DOS
'' #inclib will cause linker to look for libd1_il.a
'' when linking this executable.  The import library includes
'' some start-up code to export functions from the dynamic
'' link library when it is loaded at runtime.
#ifdef __FB_DOS__
    #inclib "d1_il"
#else
    #inclib "d1"
#endif

'' include declarations for the library from a header
#include once "d1.bi"

'' call the function in the DLL
proc_d1( __FILE__ & " : " & __FUNCTION__ )

#ifdef __FB_DOS__

'' add a module constructor to initialize the exports from
'' rtlib at run time.  Should be the first call made.
'' Careful: module constructor order is not guaranteed so
'' this is likely the only constructor that can be present
'' in the entire application, aside from the implicit
'' constructors in the DXE file that initialize it's exports.
''
Private Sub __fb_init_libfb_dxe Constructor
    DyLibLoad( "" )
End Sub

#endif


バージョン:
参照:
プログラマーのための案内に戻る
←リンク元に戻る プログラム開発関連に戻る
ページ歴史:2022-06-25 12:03:51
日本語翻訳:WATANABE Makoto、原文著作者:JeffMarshall

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

表示-非営利-継承