Pmacsのすべてがわかるかもしんない

1回「Pmacsにおける部品化のしくみ,及びDLLについて」

 

Pmacsの主な特徴の1つとして,機能の部品化を行っていることが挙げられる.この部品化の実装にはWindowsDLL機構を用いている.本稿では,部品化機構を理解する上で必要となるDLLの基本的な部分の説明を行い,その後Pmacsでの部品化機構の概要を述べる.

1.DLLの概要

DLLとは,いくつかのルーチンを実行ファイルとは別のファイルに持ち,実行前にそれらのリンクを行う為の機能である.この機能をサポートする為,WindowsではExport関数,Inport関数という形式の関数を用意している.Export関数とは,DLLから外部に公開している関数であり,Inport関数とは,他のDLLから参照する関数である.例を挙げると,アプリケーションapp.exesample.dllを使用しているとする.app.exeの中で,sample.dll内のsamp_func1という関数を呼ぶ出す場合,このsamp_func1という関数はapp.exeから見ればInport関数となる.逆にsample.dllから見た場合にはExport関数となる.どの関数をInportするか,Exportするかはコンパイル時に指定する.一般には,この例で挙げたようにDLL内の関数をExportするのが普通であるが,EXE内の関数をExportしてDLLから呼び出すこともできる.

次にDLLを使用する方法を説明する.DLLをリンクするには「暗黙のリンク」「明示的なリンク」の2つの方法がある.このうち,暗黙のリンクの方はPmacsでは用いていないので説明は省略する(暗黙のリンクの方が行うのは簡単で,通常のスタティックなライブラリと同じような感覚で使用できる).明示的なリンクはプログラム内でDLLのロードを行うものである.DLLのロードにはLoadLibrary関数を用いる.例えば,sample.dllというdllファイルをロードしたい場合には

hinst=LoadLibrary("sample.dll");

と記述する.ここで,hinstHINSTANCE型の変数である.次にDLL内の関数を参照するためにGetProcAddressを用いる.LoadLibraryを実行した後,この中のsample_funcを参照したい場合,

proc=GetProcAddress(hinst,"sample_func");

を実行することによって,procに関数へのポインタが返される(もし,DLL内に存在しない関数を指定した場合,NULLが返される.DLL内に存在してもExprot関数として宣言されていなければ,外部からはその関数は存在しないとみなされる).あとは,このポインタを使用することによって関数の呼び出しが行える.

 

2.機能部品化のしくみ

前述のようにPmacsでの部品ファイルの実体はDLLである.部品ファイルの詳細な仕様は種類によって異なるので,ここでは,共通的な概要のみを説明する.

Pmacsが実行されると,まずこれら部品ファイルのロードを行う.具体的な処理としては部品ファイルがあるディレクトリ内に存在する*.DLLのファイル全てに対してLoadLibraryを実行する.そして,それぞれの部品によって決まっている関数へのポインタを求め,記録する.例えば,描画メソッドの部品の場合,

"PMcSetPoint","PMcDrawGuideLine","PMcDrawIt","PMcCancelOne"

等の関数を含む.同じ種類の部品ファイルは同じ名前を持つExport関数から構成されている.Pmacs本体は状況に応じてこれらの関数を呼び出すことで,さまざまな処理を行う.

次に,部品側からPmacs本体になにかしらの通知を行う機構がどのようになっているかを説明する.例えば,パレットウィンドウ等の色操作を行うウィンドウ部品においては,ウィンドウ内の操作によって行われた色の変更を本体側に通知する必要がある.PmacsではこれをPmacs.exeExport関数を用意することによって行っている.具体的には色を変更する関数PMsChangeColorExportしている.DLLから色を変更したい場合には,このPMsChangeColor関数を呼び出す.その他にも,ペンを変更する関数や,画像への操作を行う関数などがExportされ,部品からの呼び出しが可能になっている.このように,Pmacsでは本体と部品それぞれにExport関数を用意し,必要に応じて呼び出し合うことによって通信を行っている.