HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2007
0802
NacWindowsAPIについて7解決


Nac

リンク

2007/8/2(Thu) 00:10:07|NO.10049

最近#funcなどWindowsAPIなどの外部DLLを使う機能が拡張されてきましたが、
HSPの動作について疑問があります。
commonフォルダにはモジュールとして使われるhspファイルが入っていますが、
そのひとつひとつでuser32.dll といった同様なDLLが使われています。

もし、ひとつのプログラム上で複数のモジュールファイルを使用した場合、
何度も何度もuser32.dllなどのファイルが読み込まれているのではないな?
と、心配になっています。

#module区間でのDLLの読み込みとはいえ同じDLLが複数読み込まれているのではないか
と不安です。


実際には、#uselibでDLLを読み込んでいるのでしょうか?
それとも API自体を命令として呼び出したときにDLLから読み込まれるのでしょうか?



この記事に返信する


f

リンク

2007/8/2(Thu) 01:06:36|NO.10050

気にしなくて良いんでね?

どうしても気になるなら、
「何の為にDLLという仕組みがあるのか」
考えてみればいいんでね?

HSPの機能拡張の為にMSが用意してくれた仕組みな訳じゃねんだし。
そーゆー使い方もできるってだけで。



Irisawa

リンク

2007/8/3(Fri) 01:14:52|NO.10074

なんか、勘違いしているように見えますがHSPにはuser32.dllのようなWindowsAPIのDLLは
付属していません。これはWin付属です。

恐らく、勘違いしているのはincludeするためのuser32.asなどの事だと思います。
これらは中で各DLLからメモリ空間内にモジュール(実行ファイルやプログラムのこと)を
読み込むための定義が書かれていますが、現在のHSP3では初回実行時に読み込まれるように
最適化されているはずです。
あと、再配布時などに実行する場合は該当DLLが必要ですが通常のWinAPIはWinに付属して
いるので必要ありません(OSによってDLLのバージョンなどAPIの動作や仕様が変わっている
こともあります)。
また、includeしたファイルはpackfileに入れたり同梱する必要はありません。

DLLというのはEXEと同様の実行モジュール(実行ファイル)であり、他の実行モジュールから
そのモジュール内のメモリ空間内にマップ(読み込む)されて、実行可能になります。
#uselibと#func系のプリプロセッサは最終的にLoadLibraryやGetProcAddressで読み込み
実行しているのと変わりません。



Nac

リンク

2007/8/6(Mon) 09:49:35|NO.10155

LoadLibraryについて調べました。
#uselibがLoadLibrary、 #funcがGetProcAddressにあたるものだとわかったのですが、

ttp://www.geocities.jp/ky_webid/win32c/058.html

ここの説明によると、なにやら
LoadLibraryは指定のDLLの関数郡の使い方の手順(?)を読み込むだけで、
実際にはDLL全体を読み込んでいるわけではない。
GetProcAddresは指定のDLLの関数を呼び出すための定義をする。
というような感じに見えます。

ということは、 定義された関数を実行するさいに、読み込まれ実行されるという形になる
と解釈したのですが間違いはないでしょうか?
LoadLibraryという名前からして不安ですが(--;



f

リンク

2007/8/6(Mon) 13:56:57|NO.10157

凄く大雑把に言うよ。

DLLは1回呼び出しされたら、後は何回呼び出されても、
最初の1回読み込んだ分が、使い回しされるだけなの。

複雑に考えなくていいの。

呼び出される度に、新たにメモリを消費するのは、
1回目、2回目、3回目と、それぞれが「別個」に動作するのに必要な
メモリを確保する分だけなの。

DLLがそういうメモリを必要とするかは、DLL次第なの。



Irisawa

リンク

2007/8/7(Tue) 22:15:26|NO.10198

実際に詳細な情報が欲しい場合は、マシン語の動作原理などを学ぶしかないと思います。
ぼくもそこまで詳しく分かっているわけではありませんが、DLLというのは各プログラムの
実行モジュールが確保しているメモリ空間とは別のWindowsが管理している共用(共通)の
メモリ空間内に読み込まれて使用されます。
(通常、普通のプログラムは仮想メモリ空間の0x00400000以降にロードされますが、DLLの
実行モジュールはバッティングしないようにロードされ、他の実行モジュール内から
呼び出されて実行されます)

http://yokohama.cool.ne.jp/chokuto/urawaza/mcn/index.html

実行ファイル(実行モジュール)とEXE、DLLなどについては静的リンクと動的リンクに
ついて調べてみてください。
ただ、完全に理解するのは難しいと思います(というかぼくも完全には理解できていない)。

かなり難しい内容ですが基本的な原理は以下のような感じになっています。

DLL内の実行モジュールはメモリ空間に読み込まれていない場合は新たに読み込まれますが
既に読み込まれていた場合は、何もしません。
LoadLibraryを使用する場合、使用する度にDLLの参照カウントと呼ばれるWindowsが
管理しているカウンターを+1します。
FreeLibraryを使用する度に参照カウントを-1します。
参照カウントが0以下になった場合、自動的にDLLの実行モジュールをメモリから解放
します。
GetModuleHandleを使用した場合、新たにDLLの実行モジュールをメモリ空間内にマップする
ようなことはせず、参照カウントも変化しません。
LoadLibraryを使用しているのにFreeLibraryを使用しなかったり、GetModuleHandleで取得
したモジュールハンドルをFreeLibraryした場合、参照カウントが狂うので誤動作の原因に
なります。



おにたま(管理人)

リンク

2007/8/8(Wed) 01:56:42|NO.10206

HSP3.1の内部では、#uselibで指定されたライブラリ名が同じものは、
モジュールが分かれていても同じものとして扱われます。
また、#funcの指定がされていても、実際にスクリプトで使用されていない場合は
登録されず、使用時のリンクも最初の呼び出し時に行われます。
ので、それほど心配するような重複はないと考えています。
気になる場合は、hspsdkに外部呼び出し部分のソースがすべて含まれていますので、
参考にしてみてください。



Nac

リンク

2007/8/8(Wed) 17:20:22|NO.10222

大変難しい仕組みでありながら詳しく説明していただきありがとうございます。
完璧に理解したという自身はもてないのですがDLLの重複読み込みが起こらないように
「使いまわし」の機能がWindowsにあるのだなということがわかりました。

HSPの内部としても分けて読み込んでいるわけではないようなので安心いたしました。
今まではuser32.asなどのAPI郡ファイルを読み込ませて、その関数の定義に基づいて
モジュールを追加していっていたので(これだと他の人が作ったモジュールを使えるように
なるまで関数の定義を変えないといけなかった)

各スクリプトファイルに定義をまとめて HSP3.1に向けて環境を整えていきたいとおもいます。



ONION software Copyright 1997-2023(c) All rights reserved.