は、私はそれが価値だ初期化するために、静的な関数を呼び出す静的定数クラスのメンバーの状況があります。にcoinitialize()および静的混乱
//A.h
class A
{
public:
static const int NUM;
static int Function();
};
//A.cpp
const int A::NUM = A::Function();
問題は::関数は()ローカル静的を持っているということですCOMライブラリを必要と変数は、CoInitializeを()を呼び出して初期化される:
//A.cpp
int A::Function()
{
static vartype m;
if(SUCCEEDED(CoInitialize(NULL)))
//Now m can be used and initialized.
// m.CreateInstance....
}
私は、以前私のWinMain関数でのCoInitialize()を呼び出した:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
{
if(SUCCEEDED(CoInitialize(NULL)))
{
MyApp* app = new MyApp;
app->Run();
delete app;
CoUninitialize();
}
return 0;
}
しかし、静的メンバ変数A :: NUMがA :: Function()の呼び出しで初期化され、WinMainのコードが実行される前にConInitialize()が呼び出されたので、私のWinMain:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
{
//if(SUCCEEDED(CoInitialize(NULL)))
{
MyApp* app = new MyApp;
app->Run();
CoUninitialize();
}
return 0;
}
は今、プログラムは正常に動作しますが、私は終了したときには、アクセス違反でクラッシュします。なぜ誰がこの現象が起こっているのかを明らかにすることはできますか?
EDIT:CoUninitialize()を呼び出すと、プログラムの実行中に静的変数が保持されるため、ローカル静的変数m(COMライブラリが必要)が問題になります。クラッシュは、このローカル変数mに関連しているようです。しかし、問題は、COMライブラリを必要とする静的変数に対して、いつCoUninitialize()を呼び出すことができますか? WinMainでifステートメントのコメントを外すと問題は解決しないようですが、CoInitialize()とCoUninitialize()を一度しか呼び出していないためです。
このタイプのクラス型のスタティック変数(そのコンストラクタでCOMライブラリを初期化する)を作成し、同じ複雑なつまり、COMライブラリは、それに続く静的メンバーのすべてに対して準備が整っていることを意味しますか?そして、プログラム終了時に静的変数が破壊されているとき、それらは常に逆の順序で破棄されるので、com_objectは最後に破棄されますか?もしそうなら、これはうまくいくようですが、A :: Function()を呼び出す他の複雑なユニットに他の静的メンバーがあると私は不運ですか? – user987280
あなたは正しいです。オブジェクトは逆の順序で破棄されます。これらの宣言を別々のユニットに置いた場合、Standardは初期化の破棄の順序を定義していません。 –
@ user987280、COMを使用する場合は、すべてのcom参照の有効期間を明示的に制御することが非常に重要です。したがって、静的変数の過度の使用を避ける方法でコードをリファクタリングすることをお勧めします。 –