hinekure.net が http://hspdev-wiki.net/ から自動クローリングした結果を表示しています。画像やリソースなどのリンクが切れています。予めご了承ください。
小ワザ/モジュール - HSP開発wiki
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS

小ワザ

モジュール?

gosubでよく使う処理を分けて記述していると、量が増えるとラベル名や変数名の管理が難しくなってきます。 これを解決する機能がモジュールです。
モジュールで有名なのはd3moduleやArtlet2Dだと思います。mod_joystickにお世話になってる人も多いのではないでしょうか?
プログラミング作業の分業化がしやすくなるので、自作モジュールを配布するユーザーもたくさんいます。

スクリプトを記述するときの使い方がプラグインと似ていますが、プラグインは配布時にdllファイル(プラグインの本体)が必要ですが、 モジュールでは出力されたexeを配布するだけで別途必要なファイルはありません。

モジュールについての詳しくは「HSP3 モジュール機能ガイド」を参照ください。

モジュールの使い方

標準で入っているモジュールを使う

d3moduleを例に取り上げます。
使いたい命令がモジュールだった場合、まずは備考欄をチェックします。

備考 d3m.hsp をインクルードする。

とありますので、使えるようにするにはスクリプトの先頭付近で、

#include "d3m.hsp"

と記述します。この記述の後であれば何処でもd3moduleの命令が使用できるようになります。
モジュールの作り方や難しいAPIの仕様などを理解しなくてもこれらが簡単に使えるようになる。これがモジュールです。

ありがちな勘違い例。「d3moduleモジュール」の命令だからこうすればいいんじゃない?

#include "d3module.as"

当然エラーです。 モジュールによっては、モジュールの名前とファイル名が異なるので必ず備考欄やreadme.txtを読みましょう。

llmod3を使う

llmod3のモジュール群はcommonフォルダ内のllmod3フォルダに格納されています。
そのためllmod3.hspをincludeする場合は次のように記述します。

#include "llmod3/llmod3.hsp"


また、このモジュールは使用する命令に応じて複数のモジュールを読み込んでやる必要があります。 どの命令でどのモジュールが必要であるかは、各命令のヘルプの備考欄に記載されています。
記載にしたがってファイルをincludeしてください。
例えばwinver命令の場合は、

備考 llmod3.hsp,winver.hspをインクルードする

とあるので、

#include "llmod3/llmod3.hsp"
#include "llmod3/winver.hsp"

と記述することでwinver命令が使用できるようになります。

またこのモジュールはuser32.asやkernel32.asと競合してしまう部分があり、併用が出来ません。

モジュールをインストールする

#include命令は指定したファイルをスクリプト内に挿入する命令です。
指定されたファイルは、
1.スクリプトと同じフォルダ。
2.HSPのインストールフォルダ内のcommonフォルダ。
の順番で探して見つかったものを使用します。

今後も使い続けたいモジュールの場合は、「HSPのインストールフォルダ内のcommonフォルダ」にモジュール本体のファイルをコピーしておくといいでしょう。
今回限りで使いたい場合は、今現在作業しているフォルダにおいておけばいいでしょう。

モジュールの作り方

#module〜#globalで囲まれた範囲がモジュールです。
スクリプト内に直接記述してもかまわないわけです。
よく使うものはモジュール用にファイルを作り、#includeで呼び出すようにすると使いやすくなります。
さらにcommonフォルダに入れておけば、モジュールのファイルを毎回作業フォルダにコピーする手間も省けます。

他のモジュールとの共存

複数のモジュールをincludeして使用していると、障害が発生することがあります。
同じ名前の命令・関数が含まれる複数のモジュールを使おうとすると、ファイルをincludeしただけでエラーが発生してしまいます。

よくあるのがAPI関数の重複だと思います。こういう経験無いでしょうか?

  • user32.asと他のモジュールを使おうとしたらエラーが出てしまった。
  • 他のモジュールとAPIがかぶるから既存のモジュール使わずに自作した。
    この問題を解決するのが#ifndef命令です。
    まず次のようなスクリプトを実行してみてください。
    Everything is expanded.Everything is shortened.
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
    
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    
    #include "user32.as"    ;←コメントにするとエラーにならない。
     
    ;###########################################################
    ;ここからモジュール
    #module
    #uselib "user32.dll"
    #func global MessageBoxA "MessageBoxA" sptr,sptr,sptr,sptr
     
    #deffunc test
        MessageBoxA hwnd, "表示文字列", "キャプションバー", 0
        return
    #global
    ;ここまでモジュール
    ;###########################################################
     
    test
    エラーが発生したと思います。
    「#include "user32.as"」をコメントにするとエラーが出なくなったはずです。
    MessageBoxAがuser32.asの中で宣言されているため このスクリプトの中で、
    #include "user32.as"
    を記述すると命令名が重複するとしてエラーが発生します。 これを回避するには次のように記述します。
Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
#include "user32.as"    ;←これを入れてもエラーにならない
 
;###########################################################
;ここからモジュール
#module
#ifndef __USER32__
    #uselib "user32.dll"
    #func global MessageBoxA "MessageBoxA" sptr,sptr,sptr,sptr
#endif
 
#deffunc test
    MessageBoxA hwnd, "表示文字列", "キャプションバー", 0
    return
#global
;ここまでモジュール
;###########################################################
 
test

__USER32__はuser32.as内部で定義された何もしないマクロです。
そのため、最初にuser32.asをincludeしていると、#ifndef〜#endifの間は無視されるようになります。
逆にuser32.asをincludeしていない場合は、#ifndef〜#endifの間は有効になり実行されるようになります。

モジュール内でAPI関数を宣言する場合はこのようにしておけば、user32.asとの競合を防ぐことが出来ます。
このほかgdi32.asなど標準のモジュールには、モジュールの重複呼び出し回避のため同じように固有のマクロが設定されています。

配布目的でモジュールを作成する場合はこのような配慮をしておくと親切ですね。

コメント

  • この場合 #func を global 指定する必要はないのですが。どう修正したものか。 -- 2011-01-23 (日) 01:28:53

URL B I U SIZE Black Maroon Green Olive Navy Purple Teal Gray Silver Red Lime Yellow Blue Fuchsia Aqua White

トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS
Last-modified: 2011-01-23 (日) 01:28:53 (1050d)