it技術:dotnet:動的dllの解放
目次
動的DLLの解放
質問内容
- 質問内容
①EXEを実行(EXEは24h常駐です。) ②動的にDLLをロード・実行し、DLLの処理終了(EXEは終了しない。) ③DLLのPGを改訂し、実行環境にコピーすると、エラーMSGがでる。 「○○.dllをコピーできません。他の人またはプログラムによって使用されています。ファイルを使用している可能性があるプログラムを全て閉じてから、やり直してください。」 EXEを24h常駐させ、実行条件によって、ロードするDLLを変更したいと考えています。 今後業務要件によってDLLを改訂する可能性があります。
回答
.NETでは、Win32の時のFreelibrary関数(DLLを呼び出しプロセスの アドレス空間から切り離す)のようなものはなく、一旦DLLを ロードしたらプロセスを終了するまでメモリに残り続けます。
(通常のDefault AppDomainにロードされている場合において)
あえて動的にする場合は、CreateDomainにて、「User AppDimain」を作成し、そこにアセンブリをロードして実行、終了時にAppDimainをUnloadすることで、動的にアセンブリを解放することが出来るようになります。
- メインコード(動的にDLLを呼ぶ側)
Dim ad As AppDomain Dim hanlde As System.Runtime.Remoting.ObjectHandle Try 'ドメインを生成 ad = AppDomain.CreateDomain("TEST") 'インスタンス生成 hanlde = ad.CreateInstance("ClassLibrary1", "ClassLibrary1.Class1") 'ラップされたオブジェクトを取得し、IClass1インターフェースにキャスト CType(hanlde.Unwrap, IClass.IClass.IClass1).test() Finally 'ドメインを開放 AppDomain.Unload(ad) End Try
参照設定:IClassのDLL(IClass1インターフェースを持つDLL)
- IClass1インターフェースを持つクラス(DLL)のコード
'インターフェース実装 Public Class IClass Public Interface IClass1 Function test() As Integer End Interface End Class
- ClassLibrary1を持つDLLのコード(今後動的に変更させるDLL)
'シリアライズを入れる必要がある。 Public Class Class1 Inherits MarshalByRefObject 'アプリケーションドメイン境界を超えてオブジェクトにアクセス Implements IClass.IClass.IClass1 'インターフェースの継承 Public Function test() As Integer Implements IClass.IClass.IClass1.test Return (任意値) End Function End Class
参照設定:IClassのDLL(IClass1インターフェースを持つDLL)
別案:シャローコピー
ロード中のアセンブリの入れ替えが目的ならシャドウコピーでよい。
アセンブリのシャドウ コピー MSDN
C# DLLの動的読み込み
参照
it技術/dotnet/動的dllの解放.txt · 最終更新: 2018/07/27 11:53 by yajuadmin