我有一个类可以完成所有必需的初始化。 目前我已经声明了这个类类型的全局对象,它正在库加载上实例化。 我已经看过其他方式,比如delaring
BOOL APIENTRY DllMain
共享库的入口点,并在进程附加上进行实际初始化。
这与让隐式全局初始化到它的工作不同吗?哪种方式更好?
答案 0 :(得分:6)
这是在C ++ DLL启动期间发生的事情:
我个人更喜欢DllMain,因为这样我可以明确地控制初始化的顺序。当您在不同的编译单元中使用全局对象时,它们将以随机顺序初始化,这可能会在截止日期前10分钟带来一些意外的惊喜。
DllMain还允许您进行每线程初始化,这是使用全局对象无法实现的。但是,它无法移植到其他平台。
P.S。您在DllMain中不需要互斥锁,因为对它的所有调用都已在进程全局关键部分下序列化。即保证两个线程不会出于任何目的同时进入它。这也是你不应该与其他线程通信,从这个函数加载其他库等的原因;有关解释,请参阅MSDN article。
答案 1 :(得分:2)
一些永远不应该做的事情from DllMain:
答案 2 :(得分:1)
您需要一个静态布尔初始化变量和一个mutex。将“initialized”静态初始化为0.在DllMain()中,调用CreateMutex()。使用bInitialOwner = 0和lpName的唯一名称,该名称对应用程序是唯一的。然后使用WaitForSingleObject()等待互斥锁。检查初始化是否为非零。如果没有,请进行初始化,然后将初始化设置为1.如果初始化为非零,则不执行任何操作。最后,使用ReleaseMutex()释放互斥锁,并使用CloseHandle()关闭它。
这是一些伪代码,省略了错误和异常处理:
initialized = 0;
DllMain()
{
mutex = CreateMutex(..., 0, "some-unique-name");
result = WaitForSingleObject(handle, ...);
if (result == WAIT_OBJECT_0) {
if (!initialized) {
// initialization goes here
initialized = 1;
}
}
ReleaseMutex(mutex);
CloseHandle(mutex);
}
答案 3 :(得分:0)
嗨我建议你更喜欢一个signleton类,你只能创建一个类的单个对象并使用它。可以使用私有构造函数创建Sigleton类。现在假设ur class A
是一个单例类,它的对象可以在你想要初始化的每个Class的构造函数中使用。请给我们一些示例代码,以便其他人可以帮助您更好。