プラグインとランタイムの作成方法を統合

いままで紹介してきた方法ではランタイム作成時にプラグインのソースを一部書き換えて、WinMainを新たに作成するというよけいな手間がかかります。

よってここでは、そのような手間をかけずにすむ方法を紹介します。

例として、プラグインを2つ作成します。
通常と違うのは、最初に呼び出される関数名をDllMainで固定し変更できないこと、ENDディレクティブのパラメータにDllStartを指定することです。その他は通常のプラグイン作成と同じです。


ファイル名:TestHpi.asm

;*********************************************************************
;タイトルに日付を持つMessageBoxを表示
;TestProc p1,p2
;TestProc2 p1,p2
;p1:メッセ−ジ
;p2:MessageBoxのタイプ
;*********************************************************************
        .386
        .model flat,stdcall
        option casemap:none

        include windows.inc
        include hspdll.inc

        include kernel32.inc
        include user32.inc
        includelib kernel32.lib
        includelib user32.lib
;*********************************************************************
.data
        fmt db "%04d年%02d月%02d日",0
.code
;*********************************************************************
DllMain PROC ,hInstDLL:HINSTANCE, fdwReason:DWORD, lpvReserved:LPVOID
        mov eax,TRUE
        ret
DllMain ENDP
;*********************************************************************
TestProc PROC EXPORT,pBms:ptr BMSCR, pMsg:ptr CHAR ,uType ,tmp  ;type 6
        LOCAL stime:SYSTEMTIME ,date[SIZEOF fmt]:CHAR

        invoke GetLocalTime,ADDR stime
        movzx eax,stime.wYear
        movzx ecx,stime.wMonth
        movzx edx,stime.wDay
        invoke wsprintf,ADDR date,ADDR fmt,eax,ecx,edx
        mov ecx,pBms
        invoke MessageBox,[ecx].BMSCR.hwnd,pMsg,ADDR date,uType
        neg eax
        ret
TestProc ENDP
;*********************************************************************
TestProc2 PROC EXPORT USES ebx ,pExinfo:ptr HSPEXINFO, tmp1,tmp2,tmp3   ;type$202
        LOCAL stime:SYSTEMTIME ,date[SIZEOF fmt]:CHAR ,pMsg ,uType

        invoke GetLocalTime,ADDR stime
        movzx eax,stime.wYear
        movzx ecx,stime.wMonth
        movzx edx,stime.wDay
        invoke wsprintf,ADDR date,ADDR fmt,eax,ecx,edx
        mov ebx,pExinfo
        ASSUME ebx:ptr HSPEXINFO
        invoke [ebx].HspFunc_prm_gets
        mov pMsg,eax
        invoke [ebx].HspFunc_prm_getdi,MB_OK
        mov uType,eax
        mov ecx,[ebx].er
        mov eax,[ecx]
        .if eax
                ret
        .endif
        mov eax,[ebx].actscr
        invoke [ebx].HspFunc_getbmscr,DWORD ptr [eax]
        mov ecx,eax     ;eaxはスタック変数のアドレス取得に使われる
        invoke MessageBox,[ecx].BMSCR.hwnd,pMsg,ADDR date,uType
        neg eax
        ret
TestProc2 ENDP
;*********************************************************************

END DllStart

ファイル名:Test_beep.asm

;*********************************************************************
;MessageBeepを呼び出す
;Beep p1
;p1:サウンドの種類
;*********************************************************************
        .386
        .model flat,stdcall
        option casemap:none

        include windows.inc
        include hspdll.inc

        include user32.inc
        includelib user32.lib

.code
;*********************************************************************
DllMain PROC ,hInstDLL:HINSTANCE, fdwReason:DWORD, lpvReserved:LPVOID
        mov eax,TRUE
        ret
DllMain ENDP
;*********************************************************************
Beep PROC EXPORT,uType:DWORD ,tmp,tmp2,tmp3               ;type 0

        invoke MessageBeep,uType
        xor eax,eax
        ret
Beep ENDP
;*********************************************************************

END DllStart

これらは2つとも、通常と同じようにプラグインを作成出来ます。


TestHpi.DLL作成用バッチファイル

@ECHO OFF
ml /c /coff TestHpi.asm
if errorlevel 1 goto error
Link /SUBSYSTEM:WINDOWS /DLL  TestHpi.obj
if errorlevel 1 goto error
goto fin
:error
echo ===============================エラー======================================
:fin
echo ===============================終了=======================================

Test_Beep.DLL作成用バッチファイル

@ECHO OFF
ml /c /coff Test_Beep.asm
if errorlevel 1 goto error
Link /SUBSYSTEM:WINDOWS /DLL  Test_Beep.obj
if errorlevel 1 goto error
goto fin
:error
echo ===============================エラー======================================
:fin
echo ===============================終了=======================================

次にランタイムを作成するメインファイルを作成します。


ファイル名:TestHrt2.asm

        include hsphrt.inc

        ;SETHRTDLL p1,p2,p3,p4,・・・
        ;p1:プラグインの名前(小文字で拡張子も含める)
        ;p2:プラグインのソースファイルのファイル名(大文字で拡張子除く)
        ;p3〜:関数名

        SETHRTDLL testhpi.dll,TESTHPI,TestProc,TestProc2
        SETHRTDLL test_beep.dll,TEST_BEEP,Beep
        SETDLLEND

SETHRTDLLマクロをプラグインの数だけ呼び出し、最後にSETDLLENDマクロを呼び出します。
これらのマクロで、プラグインの登録、初期化、初期化の正否チェック、HSPWinMainの呼び出し、プラグインの終了処理を行うコードを作成します。

このファイルとプラグインのファイルをアセンブルすることでランタイムを作成できます。注意する点は、ML.EXEのオプションでRUNTIMEマクロを定義する必要があることです。このマクロを定義することで、DllMainの名前変更や関数のエクスポート抑制などを行います。


TestHrt2.hrt作成用バッチファイル

@echo off
Rc.exe hsp2.rc
Ml.exe /c /coff /DRUNTIME TestHrt2.asm TestHpi.asm Test_Beep.asm
if errorlevel 1 goto error
Link.exe /SUBSYSTEM:WINDOWS  /NODEFAULTLIB:OLDNAMES.LIB /OUT:TestHrt2.hrt TestHrt2.obj TestHpi.obj Test_Beep.obj hsp2.res
if errorlevel 1 goto error
goto fin
:error
echo ===============================エラー======================================
:fin
echo ===============================終了=======================================

このランタイムを動作させるHSPスクリプト

;CTRL+F9でTest2.exeが作成されます
#packopt name "Test2.exe"
#packopt runtime "TestHrt2.hrt"
#uselib "TestHpi.dll"
#func TestProc  TestProc        6
#func TestProc2 TestProc2       $202
#uselib "Test_Beep.dll"
#func Beep  Beep        0
#define MB_ICONERROR    $00000010
#define MB_ICONQUESTION $00000020

TestProc "test1",MB_ICONERROR
TestProc2 "test2",MB_ICONQUESTION
Beep $FFFFFFFF

戻る