appdomain
マネージ アプリケーションの各アプリケーション ドメインは特定のグローバル変数または静的メンバー変数の独自のコピーを持つ必要があることを指定します。詳細については、「アプリケーション ドメインと Visual C++」を参照してください。
各アプリケーション ドメインにはper-AppDomain 変数の独自のコピーがあります。appdomain 変数のコンストラクターはアプリケーション ドメインがアンロードされるとアセンブリがアプリケーション ドメインに読み込まれてデストラクターが実行されるときに実行されます。
共通言語ランタイム プロセス内のすべてのアプリケーション ドメインにグローバル変数を共有する場合は__declspec(process) の修飾子を使用します。__declspec(process) は既定では下の /clr で__declspec(appdomain) は既定では下の /clr:pure です。__declspec(appdomain) は /clr:safe の下に適用されます。
__declspec(appdomain) は /clr コンパイラ オプションの 1 つが使用した場合にのみ有効です。グローバル変数静的メンバー変数または静的ローカル変数だけ __declspec(appdomain) を指定できます。これはこの動作が存在するためマネージ型の静的メンバーに __declspec(appdomain) を適用するとエラーになります。
__declspec(appdomain) を使用して スレッド ローカル ストレージ (TLS) と同様に使用できます。アプリケーション ドメインとスレッドには独自のストレージがあります。__declspec(appdomain) を使用してグローバル変数に作成されるアプリケーション ドメインごとにこのアプリケーション用のストレージを持つことができます。
プロセスの appdomain との変数に対して使用の混合に制限されています ; 詳細についてはプロセス を参照してください。
たとえばプログラムですべてのプロセスごとの変数初期化呼び出しおよびすべての per-AppDomain 変数を初期化します。したがってper-process 変数が初期化されるとすべてのアプリケーション ドメインごとに変数の値に依存することはできません。これはプロセスごとの appdomain と変数の使用 (割り当て) を使用する望ましくない。
特定のアプリケーション ドメインの関数を呼び出す方法についてはcall_in_appdomain 関数 を参照してください。
使用例
// declspec_appdomain.cpp
// compile with: /clr
#include <stdio.h>
using namespace System;
class CGlobal {
public:
CGlobal(bool bProcess) {
Counter = 10;
m_bProcess = bProcess;
Console::WriteLine("__declspec({0}) CGlobal::CGlobal constructor", m_bProcess ? (String^)"process" : (String^)"appdomain");
}
~CGlobal() {
Console::WriteLine("__declspec({0}) CGlobal::~CGlobal destructor", m_bProcess ? (String^)"process" : (String^)"appdomain");
}
int Counter;
private:
bool m_bProcess;
};
__declspec(process) CGlobal process_global = CGlobal(true);
__declspec(appdomain) CGlobal appdomain_global = CGlobal(false);
value class Functions {
public:
static void change() {
++appdomain_global.Counter;
}
static void display() {
Console::WriteLine("process_global value in appdomain '{0}': {1}",
AppDomain::CurrentDomain->FriendlyName,
process_global.Counter);
Console::WriteLine("appdomain_global value in appdomain '{0}': {1}",
AppDomain::CurrentDomain->FriendlyName,
appdomain_global.Counter);
}
};
int main() {
AppDomain^ defaultDomain = AppDomain::CurrentDomain;
AppDomain^ domain = AppDomain::CreateDomain("Domain 1");
AppDomain^ domain2 = AppDomain::CreateDomain("Domain 2");
CrossAppDomainDelegate^ changeDelegate = gcnew CrossAppDomainDelegate(&Functions::change);
CrossAppDomainDelegate^ displayDelegate = gcnew CrossAppDomainDelegate(&Functions::display);
// Print the initial values of appdomain_global in all appdomains.
Console::WriteLine("Initial value");
defaultDomain->DoCallBack(displayDelegate);
domain->DoCallBack(displayDelegate);
domain2->DoCallBack(displayDelegate);
// Changing the value of appdomain_global in the domain and domain2
// appdomain_global value in "default" appdomain remain unchanged
process_global.Counter = 20;
domain->DoCallBack(changeDelegate);
domain2->DoCallBack(changeDelegate);
domain2->DoCallBack(changeDelegate);
// Print values again
Console::WriteLine("Changed value");
defaultDomain->DoCallBack(displayDelegate);
domain->DoCallBack(displayDelegate);
domain2->DoCallBack(displayDelegate);
AppDomain::Unload(domain);
AppDomain::Unload(domain2);
}