DLL 中のデータを共有するためのコーディング要件

ダイナミック・リンク・ライブラリー (DLL) は,複数のプロセス間でデータを共有する場所として使用できる実行形式ファイルです。

コーディング要件には,cDEC$ ATTRIBUTES DLLIMPORT および DLLEXPORT コンパイラ指示文を使用することが含まれます。プログラムと DLL 中で宣言された変数とルーチンは,DLLIMPORTDLLEXPORT を使用しない限り,互いには見えません。

複数のスレッドまたはプロセスの間でデータを共有するには,次のようにします。

ここでは,以下のことについて説明します。

共通ブロック・データのエクスポートとインポート

ダイナミック・リンク・ライブラリー中のデータとコードは,それを呼び出すプログラムのデータとコードと同じアドレス空間にロードされます。ただし,プログラムと DLL 中で宣言されている変数とルーチンは,cDEC$ ATTRIBUTES DLLIMPORT および DLLEXPORT コンパイラ指示文を使用しない限り,互いには見えません。これらの命令により,コンパイラとリンカーはデータとルーチンの共有が行えるようにアドレス空間の正しい部分へのマッピングを行い,複数の実行形式ファイルの共通ブロック・データを使用できるようになります。

DLLEXPORT を使うと,DLL 中の共通ブロックがプログラムや別の DLL にエクスポートされることを宣言することができます。同じように,呼び出し側のルーチン中で DLLIMPORT を使用すると,コンパイラに対して,共通ブロックがそれを定義している DLL からインポートされることを通知することができます。

共通ブロック・データのエクスポートとインポートを行う方法

  1. Fortran DLL に組み込まれる副プログラム中に共通ブロックを作成します。cDEC$ ATTRIBUTES DLLEXPORT コンパイラ指示文の後に COMMON 文,関連するデータ宣言,およびエクスポートする手続宣言を続けて,その共通ブロックをエクスポートします。次に例を示します。
    	!DEC$ ATTRIBUTES DLLEXPORT :: /X/
    	    COMMON /X/ C, B, A
    	    REAL C, B, A
    	    END
    	    ...
    

    Fortran DLL 手続が共通ブロック宣言しか含んでいない場合,BLOCK DATA 文を使用することができます。

    	BLOCK DATA T
    	  !DEC$ ATTRIBUTES DLLEXPORT :: /X/
    	  COMMON /X/ C, B, A
    	  REAL C, B, A
    	END
    

    DLL にリンクする Fortran 手続は,次のように手続を含むことができます。

    	SUBROUTINE SETA(I)
    	  !DEC$ ATTRIBUTES DLLEXPORT :: SETA, /X/
    	  COMMON /X/ C, B, A
    	  REAL C, B, A
    	  INTEGER I
    	  A = A + 1.
    	  I = I + 1
    	  WRITE (6,*) 'In SETA subroutine, values of A and I:' , A, I
    	  RETURN
    	END SUBROUTINE
    
  2. cDEC$ ATTRIBUTES DLLIMPORT コンパイラ指示文の後に,エクスポートされる DLL 中に定義されている局所データ宣言と手続宣言を続けることで,主実行形式ファイル中で共通ブロックを参照します。次に例を示します。
    	PROGRAM COMMONX
    	  !DEC$ ATTRIBUTES DLLIMPORT:: SETA,  /X/
    	  COMMON /X/ C, B, A
    	  REAL C, B, A, Q
    	  EQUIVALENCE (A,Q)
    
    	  A = 0.
    	  I = 0
    	  WRITE (6,*) 'In Main program before calling SETA...'
    	  WRITE (6,*) 'values of A and I:' , A, I
    
    	  CALL SETA(I)
    	  WRITE (6,*) 'In Main program after calling SETA...'
    	  WRITE (6,*) 'values of A and I:' , Q, I
    
    	  A = A + 1.
    	  I = I + 1
    	  WRITE (6,*) 'In Main program after incrementing values'
    	END PROGRAM COMMONX
    
  3. ダイナミック・リンク・ライブラリーのビルドと使用」の説明に従って,DLL をビルドし,さらに主プログラムをビルドします。

モジュール内のデータ・オブジェクトのエクスポートとインポート

モジュール内のデータ・オブジェクトに DLLEXPORT プロパティを与えると,そのオブジェクトは DLL からエクスポートされます。

モジュールが別のプログラム単位で USE 文を通して使用された場合,DLLEXPORT プロパティを持つモジュール内のすべてのオブジェクトは,そのモジュールを使用するプログラム中で,DLLIMPORT プロパティを使って宣言されたものとして扱われます。このため,DLL に含まれているモジュールを使用する主プログラムは,その DLL からエクスポートされるすべてのオブジェクトの正しいインポート属性を持っていることになります。

また,モジュール内の一部のオブジェクトに DLLIMPORT プロパティを与えることもできます。DLLIMPORT プロパティを持てるのは,INTERFACE ブロック中の手続宣言と,EXTERNAL として,または cDEC$ ATTRIBUTES EXTERN コンパイラ指示文使って宣言されたオブジェクトだけです。この場合,オブジェクトは,モジュールを使用するプログラム単位によってインポートされます。

DLL の一部であるモジュールを使用しており,DLLEXPORT または DLLIMPORT プロパティを持たないモジュールに含まれているオブジェクトを使用したときの結果は未定です。

関連情報