我有一个静态const类成员的情况,它调用静态函数来初始化它的值:
//A.h
class A
{
public:
static const int NUM;
static int Function();
};
//A.cpp
const int A::NUM = A::Function();
问题是A :: Function()有一个本地静态变量,需要通过调用CoInitialize()来初始化COM库:
//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 :: Function()的调用中初始化静态成员变量A :: NUM时调用ConInitialize(),并且这将在WinMain中的代码执行之前发生,我想我可以将其从我的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;
}
现在程序运行正常,但是当我退出时它会因访问冲突而崩溃。有人能说清楚为什么会这样吗?
编辑:我认为因为静态变量应该在程序的持续时间内持续存在,所以当我调用CoUninitialize()时,本地静态变量m(需要COM库)会遇到问题。崩溃似乎与这个局部变量m有关。但问题是,我什么时候可以调用CoUninitialize()来获取需要COM库的静态变量?如果我在WinMain中取消注释if语句,问题似乎就消失了,但我认为这是因为我最终调用CoInitialize()两次而CoUninitialize()只调用一次。答案 0 :(得分:0)
首先,您可以在这种情况下使用RAII。只需定义一个简单的类,如下所示:
class com_scope
{
com_scope(com_scope const&);
com_scope& operator= (com_scope const&);
public:
com_scope()
{
::CoInitialize(NULL);
}
com_scope(DWORD dwCo)
{
::CoInitializeEx(NULL, dwCo);
}
virtual ~com_scope() throw()
{
::CoUninitialize();
}
}
然后定义一个静态const com_scope _AppComScope。在声明之前
const int A::NUM = ...
此代码将在第一次调用A :: Function之前初始化COM环境,并在执行结束时进行清理。
极有可能你的问题是你在最终使用一些com引用之前破坏了COM环境。这解释了一旦从WinMain中删除:: CoUnitialize,问题就会消失。
P.S。
虽然这是一个坏主意,但你可能不会在主线程中调用:: CoUninitialize,因为操作系统会在你的程序完成时进行清理
P.S.S。
另外,我必须承认,应该在CPP文件中定义_AppComScope,在该文件中为A :: NUM分配值。否则,标准不保证初始化的顺序