目次 次の項目

1. Windows Fortran について


1.1 Windows Fortran

 Windows対応のFortranとしては,表1に示すものがよく知られています。Windows対応とは,WindowsOS上で動作し,Windowsの操作ができるプログラムを作成できることをいいます。  本稿では,歴史的にも一般に最も広く普及しているCompaq Visual Fortranを用いたプログラミングについて解説します。

表1 Windows Fortranの種類

1
Compaq Visual Fortran90/95 "Windows システムで最もよく売れている Windows 用の Fortran 95 コンパイラです。"
2003年12月にIntel Visual Fortranに統合される。
2
Absoft Pro-Fortran "スーパーコンピュータの大手Cray Research社とAbsoftの5年に渡る技術協力の賜物である、ANSI完全準拠Fortran90が含まれており、・・・"
3
Lahey/Fujitsu Fortran90/95 "Lahey Fortran 90 は数値計算に携わる研究者に福音を齎した。広大なアドレス空間と高速性が、我々の研究室から大型計算機センターのジョブを追放した。経済性は計り知れない。"
4
Salford Fortran95 "Salford FTN95は、英国Salford Software社により開発されたFortran 95規格に合致したコンパイラです。"
個人使用は無料のようです。
http://www.silverfrost.com/11/ftn95/overview.asp
5
GNU Fortran g77/g95

Fortran77の無料コンパイラ。Dos窓で動作(Window操作は不可)。
Fortran95(g95)は以下のURLで入手できます。
http://ftp.g95.org/#Win



 Compaq Visual Fotranの変遷。

 Compaq Visual Fortranのルーツは,MSDOS上で動作するMicrosoft社のMS-FORTRANに始まります。MS-FORTRANでは,MSDOSの制限で一つの配列の大きさが64KBに制限されており,Fortranとしてはかなり使いにくいものでした。
 Windows95がレリースされたころ,DEC社に移管されAlphaシステム版と共にWindows上で動作するDigital Visual Fortranとしてデビューしました。
 DEC社がM&AによってCompaq社に吸収合併され,FortranはそっくりCompaq社に受け継がれ,Compaq Visual Fortranと名を変えました。
 CompaqもHP社に吸収合併され,HP Visual Fortranとなるかも知れません。

・追記 (2003/12/10)
 2003年12月に,HP Compaq Visual FortranはIntel社に身売りされ,Intel Fortranと統合されIntel Visual Fortranとなりました。Intel社は性能アップを強調していますが,残念なことに開発環境としてVisual Studio C++.NET が別途必要になったためWindows98では利用できなくなりました。


目次 次の項目

2. コンソールモードのプログラム


2.1 コンソールモードのプログラムの概略

 本稿はCompaq Visual Fortranを用いることを前提に解説します。 Compaq Visual Fortranは,Microsoft社が開発したMS-FORTRANの流れを受け継ぎ,DEC社がWindows対応に改良を加えたもので,その後DEC社がCompaq社に吸収合併されたために,その名称をCompaq Visual Fortranと変更されたもののようです。その最新バージョン(V6.6以降)はインテル社のCPUのPentiumVから用意されたSSE命令(4つの浮動小数点演算命令を同時に実行できる)に対応したものと推定されます。また,Pentium4では倍精度浮動小数点演算命令に対応しているようです。ただし,著者のPCは残念ながらPentiumIIなので,その力量についてはよく分かりません。従って,本稿の解説はバーションV6.1Aについて行います。

 コンソールモードのプログラムとは,DOS窓で実行されるプログラムで, Windowsの操作を行わないプログラムです。コンソールモードのプログラムは,計算を行ってその結果をテキストで画面に表示したり,ファイルに記録したりするだけの言ってみれば単純なプログラムです。一般に,Fortranのプログラムでは計算結果の出力のみが得られれば用が足りる場合が多く,グラフィックス出力などは他のソフトウェアを用いて表示させることになります。  本稿では,Fortranを用いてPS(PostScript)形式のグラフィックスデータを作成する方法を中心に解説します。PS形式のデータを作成することにより,フリーソフトのGoastViewを用いて図形表示やプリンタ出力が可能になります。事務処理によく用いる帳票出力も容易にできるようになります。

 コンソールモードのプログラムでも,旧MS-FORTRANのように一配列の大きさが64KB以内という制限はありません。理論的には2GBまで可能ですが,現実的には実装メモリ以内ということになるでしょう。

 コンソールモードのプログラムは,なんと言ってもプログラミングが容易であることと,Windowsプログラムに比べ翻訳時間の短いことが挙げられます。

 Visual Fortranは,Microsoftのプログラム開発環境であるDevelopper Studioを使用してプログラムの作成を行います。Visual Fortranを購入するとDevelopper Studioの英語版が標準添付されてきます。また,MicrosoftのVisual CやVisual Basicの日本語版を後からインストールし,統合環境を作ることができます。日本語版のVisual C等を後からインストールするとDevelopper Studioは日本語環境になります。プログラムの開発は,通常このDevelopper Studioを用いて行います。

(注)Compaq Visual Fortranは,2003年12月にIntel Visual Fortranに統合されましたので,本稿で使用しているCompaq Visual Fortranは入手できなくなっています。 (2003/12/10)

2.2 Windows Fortranの性能 (2004.01.09)

 Intel Visual Fortranの30日間試用版を入手し,コマンドモードで性能試験を行いました。ベンチマーク試験は,1000×1000の連立方程式をLU分解法を用いて倍精度で解くものです。使用した計算機は,Pentium4 1.6GHzのダイナブックでOSはWindowsXPです。なお,比較のために現在では単体CPUでは世界最高速クラスのスーパーコンピュータVPP5000でも実行してみました。結果を表2.1に示します。

 試験の主な目的は,Pentium4で強化されたSSE2を用いた倍精度での計算性能を比較するものです。これによると,同じPCでは強化命令を使用しない場合に比べ2倍以上の性能が得られています。また,単体CPUで世界最高速レベルのスーパーコンピュータに比べて1.6GHzのPCが4.47分の1の性能を発揮することができました。10年前では,PCと大型機の性能差は1000倍以上の開きがありましたが,現在ではこのレベルまで差が縮まっているようです。ただし,スーパーコンピュータを擁護するために述べると,ベンチマークで用いたLU分解法はベクトル化が十分に機能しないため,スーパーコンピュータの性能が十分に発揮することができません。スーパーコンピュータでは,今ではあまり用いられなくなった掃き出し法を用いる方がベクトル化効率が良いようです。

表2.1 Windows Fortranの性能比較

計算機とコンパイラ
実行時間
性能比
Dynabook Pentium4 1.6GHz
Compaq Visual Fortran V6.1A
14.22 秒
9.48
Dynabook Pentium4 1.6GHz
Intel Fortran V8.0
13.91 秒
9.27
FMV Pentium4 3.2GHz
Compaq Visual Fortran V6.1A
11.45 秒
7.63
FMV Pentium4 3.2GHz
g95 試用版
7.00 秒
4.67
Dynabook Pentium4 1.6GHz
Intel Fortran V8.0
SSE2ベクトル化機能使用
6.70 秒
4.47
VPP5000 9.6Gflops
VPP Fortran
1.50 秒
1.00
dynabook R731/39EB i7-2640M 3.5GHz
Compaq Visual Fortran V6.1A
1.36 秒
0.73
HPC2500 8.3Gflops
Fujitsu Fortran
0.97 秒
0.65

(注)Intelの資料によると,SSE(Streaming SIMD Extensions)によるベクトル化とは,以下のようにDOループ内の演算を変更し,最大4つの単精度実数演算を同時に処理する機能です。

・元のDOループ

     do i = 1, n
       a(i) = b(i) + c(i)
     end do

・ベクトル化したDOループ

     i = 1
     do while (i < (n - mod(n,4)))
       a(i:i+3) = b(i:i+3) + c(i:i+3)
       i = i + 4
     end do
     do while (i <= n) 
       a(i) = b(i) + c(i)
       i = i + 1
     end do

 なお,SSEでは32ビット浮動小数点データ4組の演算を同時に行うことができ,SSE2(Streaming SIMD Extensions 2)では64ビット浮動小数点データ2組の演算を同時に行うことができる,とあります。

(訂正:2007/01/06)
 筆者は当初,SSE2でも倍精度実数演算を4組同時に実行できると思っていました。IntelのCPU(Pentium4)は異なる命令を最大3つ同時に実行できるスーパースケーラの機能があり,SSE2を用いない場合にはこの機能によって上記の性能差になったものと考えていました。よく調べてみると,Pentium4の浮動少数点演算ユニットは1組しかないようです。

 上記の性能試験では,SSE2を用いた場合と使用しない場合で性能差が2倍になっていますが,なるほど当然といえる結果のようです。


目次 次の項目

3. コンソールモードプログラムの作成


3.1 コンソールモードのプログラムの作成

 コンソールモードのプログラムを作成するには,次の手順に従って行います。

1) Developper StudioのFortran開発環境を起動し,プルダウンメニューの'File'を選択し,'New'を選択します。

2) 図3.1 のようなプロジェクト設定画面になるので,'Fortran Console Application'を選び,'Project Name'に任意の名前を指定します。

図3.1 新規プロジェクト作成画面

3) プロジェクト・ウィザード・ダイアログでは,プロジェクト・ファイルのディレクトリなど必要なオプションを設定します。
 ソースプログラムを新規に作成するには,ツールバーの'Files'を選択しファイル・ダイアログで'Fortran Free Format Source File' 又は,'Fortran Fixed Format Source File'を選択します。Windowsプログラムでは,Fortran90の文法を用いますのでFree Formatを選択し,ファイル修飾子には.f90を付けるようにします。コンソールモードのプログラムでは,旧Fortan77の文法も使用できます。この場合にはファイル修飾子に.for又は.fを付けます。
 Fortran95以降はFree Formatに統一されるようです。

4) プログラムの実行に必要なその他のソースファイルがあれば'Project'メニューの'Add to Project -> Files...'を選択し設定します。

5) 翻訳は,'Build'メニューで'Build'又は,'Rebuild'を選択します。

6) 翻訳して実行する場合は,Ctl+F5キーを押します。

(注)新しいOS(Windows Vista,Windows 7)で実行するときに,VCSPAWN.EXEが特権利用者でないと実行できない旨のエラーが出る場合があります。デスクトップのDevStudio(Visual Studio)のアイコンを右クリックし,プログラムを特権利用者として実行するように設定すれば回避することができます。


目次 次の項目

4. 図形処理プログラム


4.1 図形処理プログラムの概要

 コンソールモードのプログラムでは,基本的にWindowを操作して図形やグラフを出力することができません。 従って,計算結果を図形表示するためには,図形データを一旦PS(PostScript)形式などに変換して出力します。 PS形式の図形データを画面表示したり,プリンタに印刷するにはフリーソフトのGSviewなどがよく用いられています。 ここで紹介する図形ルーチンは基本的にはカルコンプ社のプロッタールーチンの仕様に準じていますが,画面やカット紙に出力することを前提にしているため,画面定義などが独自の仕様になっています。 詳細は図形出力の手引を参照してください。

図4.1 図形処理システムの概要

4.2 図形出力のサンプル

 右図は図形ルーチンを用いて作図した1例です。
以下にプログラムのサンプルを示します。

! ... Simultaneous equations solved by Gauss-Zidel method.
      REAL A(3,3)/7.0,1.0,3.0,2.0,10.0,-1.0,-1.0,-2.0,9.0/, &
      B(3)/8.0,9.0,11.0/,X(3)/3*0.0/,E(10,3),XP(10)
      DATA XP(9),XP(10)/0.0,2.0/,EPS/1.0E-7/
      DO 10 K=1,8
      CALL GAUSZ(A,B,X,3,3)
      DO 20 J=1,3
      E(K,J)=ABS(1.0-X(J))+EPS
   20 CONTINUE
      XP(K)=K
   10 CONTINUE
      CALL XINT('A4P,FILE=SAMPLE.PS')
      CALL XVIEWP(-1.0,-1.0,6.0,13.0)
      CALL NEWPEN(1)
      CALL FRAME (-1.0,-1.0,6.0,13.0)
      CALL SCALG(E,12.0,8,1)
      DO 30 J=2,3
      E(9,J)=E(9,1)
      E(10,J)=E(10,1)
   30 CONTINUE
      CALL CLRPEN(12)    ! 1:RED
      CALL LGLIN(XP,E(1,1),8,1,1,0,1)
      CALL CLRPEN(22)    ! 2:GREEN
      CALL LGLIN(XP,E(1,2),8,1,1,1,1)
      CALL CLRPEN(32)    ! 3:BLUE
      CALL LGLIN(XP,E(1,3),8,1,1,4,1)
      CALL CLRPEN(1)
      CALL LGAXS(0.0,0.0,'ERR', 3,12.0,90.0,E(9,1),E(10,1))
      CALL LGAXS(5.0,0.0,'ERR',-3,12.0,90.0,E(9,1),E(10,1))
      CALL AXSPR2(0.06,0.0,-1)
      CALL AXISB(0.0,0.0,'ITERATIONS',-10,5.0,0.0,XP(9),XP(10))
      CALL XEND
      STOP
      END
!
      SUBROUTINE GAUSZ(A,B,X,K,N)
      REAL A(K,N),B(N),X(N)
      DO 10 I=1,N
      R=B(I)
      DO 20 J=1,N
      R=R-A(I,J)*X(J)
   20 CONTINUE
      X(I)=X(I)+R/A(I,I)
   10 CONTINUE
      RETURN
      END

 このサンプルプログラムは,連立方程式を反復法のガウスザイデル法を用いて解くときに,反復を繰り返す度に誤差が小さくなっていく様子をグラフにしたものです。 単精度の計算ではほぼ8回の反復で6桁の精度で解が求まっていることを表しています。
 一般に,このような反復法は微分方程式を解くような場合に用いると収束が早いので有利だといえます。

4.3 図形処理サブルーチン

 サンプルプログラムで引用しているXINTからXENDまでのサブルーチンが図形処理サブルーチン(PSPLOT)です。 このサブルーチン(群)は,図形ルーチンの初期化(XINT),終了処理(XEND)から,画面の設定(XVIEWP),直線の作画(PLOT,LINE),文字列の描画(SYMBOL,JCHAR)などの基本サブルーチンと座標軸の作画(AXIS),円弧の作画(CIRCL)などの拡張サブルーチンからなる多くのプログラムで構成されています。 図形処理サブルーチンでは,図形データを汎用性の高いPS(PostScript)形式で出力します。 図形処理サブルーチンを用いて作画した図は,フリーソフトのGSviewなどでディスプレイ画面に表示したり,プリンタに印刷したりすることができます。

基本サブルーチン(PSPLOT)

・図形ライブラリ(XY.LIB)のダウンロード(522KB) 09/05/14 


目次 次の項目

5. ライブラリの作成


5.1 ライブラリの作成

 Fortranのプログラムでは,完成されたサブルーチンや関数サブルーチンはライブラリの形式にして保存しておきます。ライブラリを用いると実行の度に翻訳をしなくて済みます。特に他のプログラムにも共通に用いられるようなサブルーチンや関数サブルーチンはライブラリの形式にして保存しておくと便利です。

1) 3.1と同様に,Developper StudioのFortran開発環境を起動し,プルダウンメニューの'File'を選択し,'New'を選択します。

2) 図5.1 のようなプロジェクト設定画面になるので,'Fortran Static Library'を選び,'Project Name'に任意の名前を指定します。

図5.1 ライブラリ作成プロジェクトの設定画面

3) 3.1と同様にソースプログラム等の登録をした後,'project'の'setting'メニューを選択し,'library'を選択すると,図5.2のような画面になるので'Output file name'の項目に出力するライブラリのファイル名を指定します。また,ライブラリは通常エラーのない完成されたプログラムなので,'Settings For'の項目には'Win32 Release'を選択し,実行速度の速いオブジェクトを生成するように指定しておきます。

図5.2 出力ファイルの設定画面

4) 'Build'メニューの'Build xxxx.LIB'を実行すると,ライブラリ形式のファイルが作成されます。

5.2 ライブラリの使用

 このようにして作成したライブラリを引用してプログラムを実行するには,そのプロジェクトの設定で使用するライブラリを指定します。'Project'メニューの'Settings'を選択し,'Link'を選択すると,図5.3のような画面になるので,'Object/library modules'の項目に引用するライブラリファイルの名前を追加します。また,そのファイルの存在するパスを'Additional library path'の項目に設定しておきます。

図5.3 ライブラリを使用するときの設定画面

5.3 ライブラリの管理

 いくつかのサブルーチンや関数サブルーチンは,ライブラリ形式にして一つのファイルにまとめておくと管理上便利です。ライブラリ形式のファイルの統合は,以下のように行います。

1) 'スタート'キーから'Fortran Command Prompt'プログラムを起動し,MS-DOSプロンプトウィンドウを開きます。

2) LIBコマンドを用いてライブラリファイルの統合を行います。

 使用例

    Setting environment for using Visual Fortran tools
    C:\Program Files\DevStudio\Common\MSDEV98\My Projects> D:
    D:\> CD MYLIB
    D:\MYLIB> LIB /OUT:XY.LIB PSPLOT.LIB XYSUB.LIB
    D:\MYLIB> EXIT

 この例では,DドライブのMYLIBというディレクトリにあるライブラリ,PSPLOT.LIBとXYSUB.LIBという2つのライブラリを統合し,XY.LIBというライブラリファイルを作成しています。

 この他にLIBコマンドでは,統合されたライブラリ(オブジェクトモジュール)の一覧リストの出力や,不要となったライブラリの削除などができます。

3) DUMPBINコマンド

 ライブラリファイルの中に含まれるサブルーチンや関数などの外部参照名を表示するには,DUMPBINコマンドを用います。DUMPBINコマンドはVisual Studioの\VC98\binディレクトリに含まれています。使用方法はLIBコマンドと同様に,'Fortran Command Prompt'プログラムを起動し,MS-DOSプロンプトウィンドウを開きます。

 使用例

    Setting environment for using Visual Fortran tools
    C:\Program Files\DevStudio\Common\MSDEV98\My Projects> D:
    D:\> CD MYLIB
    D:\MYLIB> DUMPBIN /LINKERMEMBER XY.LIB | MORE
    D:\MYLIB> EXIT




目次 次の項目

6. 図形処理の応用(日本語出力を用いた帳票出力)


6.1 図形処理の応用(日本語出力を用いた帳票出力)

 統計処理などでは,計算処理を行った結果を帳票の形式で清書してプリントしたいことが多くあります。第4章の図形処理プログラムライブラリとフリーソフトのGsviewを用いると罫線の出力や日本語を含む文字のプリント出力が任意の位置に容易に出力することができます。

図6.1 帳票出力の例

プログラム例



 バイナリサーチ

このプログラムでは,計算機システムを使用したCPU時間を利用者毎に集計しています。アカウント情報に含まれる利用者番号と,それに対応する利用者番号毎に用意したCPU時間を累積するための領域位置を特定するのにバイナリサーチという手法を用いています。登録利用者数をNとしたときに,通常のシーケンシャルサーチでは目的の領域位置を特定するのに平均N/2回の比較が必要ですが,バイナリサーチでは,logN/log2 回で済むことになります。ちなみにN=1000の時は約10回という計算になります。実際のプログラムでは,2分したときの残り件数が一定の値以下になった時には処理効率を考えてシーケンシャルサーチに切り替えます。また,当然のことながらバイナリサーチができるのは,比較するキーが昇順又は降順に並んでいなければなりません。
 一般的にはこのような集計作業では,集計するデータと集計先データを昇順にソートしてから付き合わせるやり方が普通かも知れません。しかし,このような方法では集計するデータの件数が多くなるとソートにかかる時間が相当多くかかってしまいます。バイナリサーチを用いて効率よく突き合わせを行えば集計するデータをソートする必要がないので,大型コンピュータを用いて行うような集計作業がパソコンでも十分可能になります。


目次 次の項目

7. 図形処理の応用(有限要素法を用いた構造解析)


7.1 図形処理の応用(有限要素法を用いた構造解析)

 図形処理ルーチンの応用例として,有限要素法を用いて簡単な構造解析を行った結果を図形表示する場合を紹介します。 例では,均一な材質の中心に穴のあいた板の一方から力を加えたときの力の加わり方と,板の変形を計算しています。計算量を節約するため,対称性を用いて穴の中心から4分の1だけを計算しています。

出力例

プログラム例


目次 次の項目

8. 図形処理の応用(三次元図形の表示)


8.1 図形処理の応用

 図形処理ルーチンを拡張し,三次元図形を表示するプログラムを紹介します。

 三次元表示には,デカルト座標の右手座標系を用いています。また,三次元の図形を二次元の平面に投影するには,2点投影法を用いています。図形ルーチンの出力は,PS(PostScript)形式で出力しているため,上書きで出力されます。従って,隠れて見えない部分などの陰面消去を比較的容易に行うことができます。

出力例

・参考資料

 山口富士夫:「コンピュータディスプレーによる図形処理工学」日刊工業新聞社

プログラム例


目次 次の項目

9. APIを用いたファイル入出力


9.1 APIを用いたファイル入出力

 APIを用いてファイル入出力を行うと,Fortranの標準の入出力に比べよりメカニックなファイル操作ができます。例えば,画像データの入出力を標準入出力で行おうとすると,不要なCR/LFレコードが記録されてしまい,うまくいかない場合があります。入出力操作の前に入出力位置を指定することもできます。

・CreateFile関数
 CreateFile関数は,ファイルをオープンします。既存のファイルを読む場合にもこの関数を用います。

   integer function CreateFile(
  lpFileName,            ! ファイル名(NULLで終わる文字列)
  dwDesiredAccess,       ! アクセスタイプ(入出力)
  dwShareMode,           ! シェアモード
  lpSecurityAttributes,  ! セキュリティ属性(Windows95では不適用)
  dwCreate,              ! アクション
  dwAttrsAndFlags,       ! ファイル属性
  hTemplateFile          ! 拡張属性を与えるテンプレートファイルのハンドル
  )

   戻り値:成功時は指定されたファイルのハンドル,失敗時はINVALID_HANDLE_VALUE。

 lpFileNameは,オープンするファイル名を指定します。
  NULLで終わる文字列を指定するには,C型の文字列を使用します。
   例:"D:\\TEMP\\MYFILE.BMP"C  \記号は2個続けて記述します。

 dwDesirdAccessは,ファイルへのアクセス(入出力の別)を指定をします。
  0 ならば,実際にアクセスせずにデバイス属性を問い合わせる。
  GENERIC_READは,読みとり。ファイルポインタの移動可能。
  GENERIC_WRITEは,書き込み。ファイルポインタの移動可能。
   入出力を行うには,IOR(GENERIC_READ,GENERIC_WRITE)で指定します。

 dwShareModeは,共有の可否を指定します。
  複数のアプリケーションから同じファイルを読み書きする場合には共有を指定します。
  0ならば、ファイルを共有しません。
  FILE_SHARE_READは,読み込みを共有します。
  FILE_SHARE_WRITEは,書き込みを共有します。

 dwCreateは,ファイルの作り方を指定します。
  CREATE_NEWならば,新しいファイルを作ります。既にある場合は関数は失敗します。
  CREATE_ALWAYSは,新しいファイルを作ります。既にある場合は上書きします。
  OPEN_EXISTINGは,ファイルをオープンしますが,存在しない場合は関数が失敗します。
  OPEN_ALWAYSは,ファイルをオープンしますが,CREATE_NEWと同じです。
  TRUNCATE_EXISTINGは,ファイルをオープンしますが,オープン後切りつめて0バイトになります。
   そのファイルがない場合は関数が失敗します。

 dwFlagsAndAttributesは,ファイル属性を指定します。
  FILE_ATTRIBUTE_ARCHIVEは,アーカイブファイルの指定。
  FILE_ATTRIBUTE_NORMALは,属性を持ちません。他のフラグと用いると無効。
  FILE_ATTRIBUTE_READONLYは,読みとり専用。
  FILE_ATTRIBUTE_SYSTEMは,システムファイル。
  FILE_ATTRIBUTE_TEMPORARYは,テンポラリー用。
 などです。

 hTemplateFileは,特殊な使い方ができますが通常はNULLで大丈夫です。

・CloseHandle関数
 CloseHandle関数は,処理の終わったファイルをクローズします。

   logical function CloseHandle(
  hObject               ! クローズするオブジェクトのハンドル
  )

   戻り値:成功時は非0,失敗時は0。

・SetFilePointer関数
 SetFilePointer関数は,ファイルポインタを任意の位置にセットします。

   integer function SetFilePointer(
    hFile,                ! ファイルハンドル
    lDistanceToMove,      ! ファイルポインタを移動する距離
    lpDistanceToMoveHigh, ! 距離64ビット分の上位32ビット
    dwMoveMethod          ! 移動の仕方
   )

   戻り値:成功時は新しいファイルポインタ,失敗時はINVALID_SET_FILE_POINTER。

 lDistanceToMoveは,ファイルポインタを移動する距離です。(32ビット)
 lpDistanceToMoveHighは,移動距離が32ビットで表しきれないとき,64ビットの上位32ビットのポインタです。
 dwMoveMethodは,移動開始点です。
  FILE_BEGINは,開始点が0又はファイルの先頭です。
  FILE_CURRENTは,ファイルポインタの現在位置が開始点です。
  FILE_ENDは,ファイルの最後(EOF)が開始点となります。

・ReadFile関数
 ReadFile関数は,ファイルを読み込みます。

   logical function ReadFile(
    hFile,               ! ファイルハンドル
    lpBuffer,            ! データを受け取るバッファのアドレス
    nNumberOfBytesToRead,! 読み込むバイト数
    lpNumberOfBytesRead, ! 読み取ったバイト数を格納する変数のアドレス
    lpOverlapped         ! CreateFileでFILE_OVERLAPPEDを使わなければ関係ない
   )

   戻り値:成功時は非0,失敗時は0。

・WriteFile関数
 WriteFile関数は,ファイルに書き込みを行います。

   logical function WriteFile(
    hFile,               ! ファイルハンドル
    lpBuffer,            ! データを書き出すバッファのアドレス
    nNumberOfBytesToRead,! 書き込むバイト数
    lpNumberOfBytesRead, ! 実際に書き込まれたバイト数を格納する変数のアドレス
    lpOverlapped         ! CreateFileでFILE_OVERLAPPEDを使わなければNULLでよい
   )

   戻り値:成功時は非0,失敗時は0。

・プログラムサンプルと実行例

 このプログラム例は,図形ルーチンの基本処理部分の一部を応用し,メインプログラムで用意した3次元配列IA上に,RGBの3色に相当する2値のイメージ画像で作画し,BMP形式の画像ファイルとして出力しています。BMPの画像データの入出力を行うときにAPIを用いています。BMP画像の表示には適当なビューアを用います。

 ファイル入出力を行うAPIを引用しているサブルーチンでは,USE文でDFWINAを指定しておきます。

プログラム例


目次

10. データベースのアクセス


10.1 データベースのアクセス

 FortranプログラムからOracleやAccessのデータベースをアクセスすることができます。データベースをアクセスするには,Windowsが提供するAPIのODBC32ライブラリを用いて,SQL(Structured Query Language)コマンドを発行します。 その概略を図10.1に示します。


図10.1 データベースのアクセスの概略

・ODBCデータソースの定義

 プログラムからデータベースを参照するために,ODBC(Open Database Connectivity)の定義をしておきます。ODBCの定義は,コントロールパネルの設定画面でODBCデータソースを選択すると,図10.2の画面になります。
 図ではユーザーDSNを選択し,追加を選んでAccessのデータベースを参照するようにaddressという名前をつけてAccess用のドライバとデータベース名(*.mdb)を設定しています。Fortranのプログラムでは,アクセスするデータベースをここで設定したaddressという名前で引用します。



図10.2 ODBCデータソースの設定画面

・Accessデータベースの例

 Accessデータベースの例として,図10.3のような住所録を作ってみます。住所録には,名前,郵便番号,住所,電話番号の他に名前の呼び方をカナで入力したものをアクセスするときのキーとなるように項目を追加しておきます。



図10.3 Accessデータベースの例(架空の住所録)

・ODBCライブラリの設定

 Microsoft Visual StudioのFortran開発環境でODBCのAPIを使用するには,ProjectのSettings画面を開き図10.4のようにLinkのCategoryでInputを選択し,Object/library modules:にODBC32.LIBを指定し,Additional library path:にはVisual Fortranに付加されているVC用のライブラリのディレクトリを追加しておきます。



図10.4 ODBCライブラリの設定

・APIの説明

 次に示すプログラムのサンプルで使用するAPIについて説明します。詳しくは,「Windows95 APIバイブル3」[翔泳社]を参照してください。

SQLAllocEnv関数 SQLAllocEnv関数は, ODBC呼び出しのインターフェースを初期化し,アプリケーションとの接続に使う環境ハンドルにメモリを割り当てます。 他のODBC関数の呼び出しに先立って呼び出します。
 SQLAllocEnv(
  phenv      ! 割り当てられた環境ハンドルを受け取るHENV変数のポインタ。
  )
SQLAllocConnect関数 SQLAllocConnect関数は,特定のODBC接続に関係する情報を参照するための接続ハンドルを取得します。
 SQLAllocConnect(
    henv            ! SQLAllocEnv関数で取得した環境ハンドル。
    phdbc           ! 接続ハンドルを受け取るHDBC変数のポインタ。
  )
SQLConnect関数 SQLConnect関数は,ドライバをロードし,データソース名,ユーザID, 及びパスワードによってデータソースとの接続を確立します。
 SQLConnect(
    hdbc            ! SQLAllocConnect関数で取得した接続ハンドル。
    szDSN           ! データソース名を格納するバッファのポインタ。
    cbDSN           ! szDSNバッファの長さ。
    szUID           ! ユーザ名を格納するバッファのポインタ。
    cbUID           ! szUIDバッファの長さ。
    szAuthStr       ! パスワードを格納するバッファのポインタ。
    cbAuthStr       ! szAuthStrバッファの長さ。
  )
SQLAllocStmt関数 SQLAllocStmt関数は,ステートメントハンドルにメモリを割り当て,ステートメントハンドルと接続ハンドルを対応付けます。
 SQLAllocStmt(
    hdbc            ! SQLAllocConnect関数で取得した接続ハンドル。
    phstmt          ! ステートメントハンドルを受け取るバッファのポインタ。
  )
SQLExecDirect関数 SQLExecDirect関数は,SQL文を翻訳・実行します。
 SQLExecDirect(
    hstmt           ! SQLSQLAllocStmt関数で取得したステートメントハンドル。
    szSqlStr        ! 実行するSQL文を格納するバッファのポインタ。
    cbSqlStr        ! szSqlStrバッファの長さ。
  )
SQLBindCol関数 SQLBindCol関数は,結果セット列に記憶域(変数)とデータ型を割り当てます。 この関数を実行した後SQLFetch関数を実行すると,バインドされた列のデータが指定された変数に格納されます。
 SQLBindCol(
    hstmt           ! SQLSQLAllocStmt関数で取得したステートメントハンドル。
    icol            ! 結果セットの列番号(一番左の列が1)。
    fCType          ! 結果セットのCデータ型。
  )

 fCTypeには次の表の値が指定できます。

説  明
 SQL_C_BINARY  バイナリ値。
 SQL_C_BIT  ビット値。
 SQL_C_CHAR  文字列データ。

・実行例

 このプログラム例は,図10.3に示したAccessデータベース(ADRTBL1)から最大100レコード読み込んで標準出力画面に出力するものです。なお,キーという項目の順に読み込むときは,SQLのSELECT文に"ORDER BY キー"を付加します。

 ODBC32ライブラリは,VC用のものをFortranから引用するので,使用するライブラリは,!DEC$文でCとのインターフェースを定義しておきます。なお,関数は整数型であることに注意してください。そのため,implicit文でSで始まる変数(関数)を整数型に宣言しています。

プログラム例