DLLのリロードについて
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2011/9/5 22:41:33
Declare の部分を別プロセスにしてしまうというのは如何でしょうか。
プロセス間通信を行う必要はありますが、EXE が別ならば再起動も簡単に行えるでしょうし。
EXE を分けたくないのであれば、LoadLibrary/FreeLibrary を使って
DLL を動的にロードするという手法もあります。
http://dobon.net/vb/dotnet/links/extractarchive.html
プロセス間通信を行う必要はありますが、EXE が別ならば再起動も簡単に行えるでしょうし。
EXE を分けたくないのであれば、LoadLibrary/FreeLibrary を使って
DLL を動的にロードするという手法もあります。
http://dobon.net/vb/dotnet/links/extractarchive.html
投稿者 hajime  (社会人)
投稿日時
2011/9/8 07:30:41
魔界の仮面弁士さんありがとうございます。
LoadLibrary/FreeLibraryを使ってみようと思います。
こちらでうまくいかない場合は別プロセスを考えます。
LoadLibrary/FreeLibraryを使用する場合、
スレッドを10個立てる場合に、スレッド毎にLoadLibrary/FreeLibraryを行う必要があるのでしょうか?
この部分の理解に苦しんでおります。
お分かりでしたら、ご教示よろしくお願いいたします。
よろしくお願いいたします。
LoadLibrary/FreeLibraryを使ってみようと思います。
こちらでうまくいかない場合は別プロセスを考えます。
LoadLibrary/FreeLibraryを使用する場合、
スレッドを10個立てる場合に、スレッド毎にLoadLibrary/FreeLibraryを行う必要があるのでしょうか?
この部分の理解に苦しんでおります。
お分かりでしたら、ご教示よろしくお願いいたします。
よろしくお願いいたします。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2011/9/10 18:49:31
試したわけでは無いですが、私の認識としては:
・LoadLibrary 自体は、プロセスに対してマップされる。
・複数スレッドからの同時呼び出しに耐えられるかどうかは DLL 次第。
・同一プロセス上の複数のスレッドからそれぞれ LoadLibrary しても問題は無いが、
ロードされる DLL のメモリ空間は、呼び出し元スレッドではなく、その親プロセスに配置される。
という認識ですね。
> スレッドを10個立てる場合に
DLL を複数のスレッドから呼び出せるかどうかは、ケースバイケースだと思います。
unlha32.dll などはマルチスレッドでの呼び出しに対応していませんし、一方で、
basp21.dll はマルチスレッド環境での利用を前提に設計されています。
たとえばその DLL がグローバル変数を利用していた場合、その変数は
LoadLibrary もしくは Declare した親プロセスのメモリ空間に配置されるので、
実行時には、親プロセスにとってのグローバル変数と同種の状況に置かれ、
結果としてスレッドセーフとはなりません。(呼び出し元で同期制御が必要)
複数同時に呼び出したいのであれば、マルチスレッドで動作させるのではなく、
マルチプロセスで扱った方が良いでしょう。あるいは、DLL を複数個用意するとか。
とはいえ、その DLL が同時利用不可なリソース(Clipboard や COM ポート等)を操作している場合には、
たとえマルチプロセスで動作させても並列動作とはならず、結局は同期制御が要求されることもあります。
以下はVB 側の話では無いですが、一応参考情報として。
http://support.microsoft.com/kb/118816/ja
http://www.sado.co.jp/system/taka/TLS/default.htm
http://konuma.txt-nifty.com/blog/2005/12/loadlibrary_5427.html
http://ruffnex.oc.to/kenji/text/dll_inj/
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200903/09030026.txt
・LoadLibrary 自体は、プロセスに対してマップされる。
・複数スレッドからの同時呼び出しに耐えられるかどうかは DLL 次第。
・同一プロセス上の複数のスレッドからそれぞれ LoadLibrary しても問題は無いが、
ロードされる DLL のメモリ空間は、呼び出し元スレッドではなく、その親プロセスに配置される。
という認識ですね。
> スレッドを10個立てる場合に
DLL を複数のスレッドから呼び出せるかどうかは、ケースバイケースだと思います。
unlha32.dll などはマルチスレッドでの呼び出しに対応していませんし、一方で、
basp21.dll はマルチスレッド環境での利用を前提に設計されています。
たとえばその DLL がグローバル変数を利用していた場合、その変数は
LoadLibrary もしくは Declare した親プロセスのメモリ空間に配置されるので、
実行時には、親プロセスにとってのグローバル変数と同種の状況に置かれ、
結果としてスレッドセーフとはなりません。(呼び出し元で同期制御が必要)
複数同時に呼び出したいのであれば、マルチスレッドで動作させるのではなく、
マルチプロセスで扱った方が良いでしょう。あるいは、DLL を複数個用意するとか。
とはいえ、その DLL が同時利用不可なリソース(Clipboard や COM ポート等)を操作している場合には、
たとえマルチプロセスで動作させても並列動作とはならず、結局は同期制御が要求されることもあります。
以下はVB 側の話では無いですが、一応参考情報として。
http://support.microsoft.com/kb/118816/ja
http://www.sado.co.jp/system/taka/TLS/default.htm
http://konuma.txt-nifty.com/blog/2005/12/loadlibrary_5427.html
http://ruffnex.oc.to/kenji/text/dll_inj/
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200903/09030026.txt
SATAを介してドライブと通信を行っているのですが、
動作させているソフトを立ち上げた状態で、ドライブの電源をOFFし、再度ONすると、
通信が出来なくなります。
この状態で、ソフトを再度立ち上げ直すと通信が出来るようになります。
マイコンピュータ上でもドライブの電源OFF・ON後、認識していることを確認しています。
構成ですが、
VC++で通信用のDLLを作成しています。
VBからは、そのDLLをDeclareで使用しています。
DLLの中には、通信用のSCSIドライバ(客先から入手)があり、
こちらで作成したのは、SCSIドライバの関数を呼び出しているだけです。
客先のアプリケーションは(C?)、ドライブ電源をOFF・ONしてもそのまま使うことが出来るのですが、
こちらで作成した(VB)ソフトでは通信が出来なくなります。
客先からも現在聞くことも出来ない状況で、原因も分からない状態です。
そこで、DLLをリロードのようなことをすればうまくいくのではと思い、色々調べたのですが、
解が見つかりません。
他に原因として推測したのは、ドライブ電源をOFFすると、一度確立したドライブとの通信が切れて、
再度電源をONしたときには、別の通信経路(ID?など変化)してしまっているのではと推測しています。(不明)
また、VC++でのDLL作成方法が悪いのか、VBでの呼び出し方が悪いのか、迷走しています。
DLLのリロードの方法がいいのか悪いのかも分からず、
他の方法などもありましたら、どなたかご教示いただけないでしょうか。
よろしくお願いいたします。