加载 DLL 不初始化静态 C++ 类

Loading DLL not initializing static C++ classes(加载 DLL 不初始化静态 C++ 类)

本文介绍了加载 DLL 不初始化静态 C++ 类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个正在运行时加载的 DLL.DLL 依赖于内部工作的静态变量(它是 std::map),该变量在 DLL 中定义.

I have a DLL that is being loaded at run-time. The DLL relies on a static variable for internal workings (it is a std::map), this variable is defined within the DLL.

当我在加载后从 DLL 调用第一个函数时,我从 DLL 得到一个 SegFault,映射从未被初始化.从我从 DLL Loading 中读到的所有内容中,静态和全局数据初始化应该在调用 DLLMain 之前发生.

When I call the first function from the DLL after loading, I get a SegFault from the DLL, the map was never initialized. From everything I have read from DLL Loading, static and global data initialization should happen before even the call to DLLMain.

为了测试静态初始化,我添加了一个静态结构来打印一条消息,甚至还加入了一个断点以进行良好的衡量.

To test static initialization I added a static struct that prints out a message, and even threw in a breakpoint for good measure.

static struct a
{
  a(void) { puts("Constructing
"); }
}statica;

在调用 DLLMain 或函数之前没有消息或中断.

There was no message, or break before DLLMain or the function is called.

这是我的加载代码:

  dll = LoadLibrary("NetSim");
  //Error Handling

  ChangeReliability   = reinterpret_cast<NetSim::ChangeReliability>
                        (GetProcAddress(dll, "ChangeReliability"));


ChangeReliability(100);

我已经验证了 dll 版本是正确的,多次重建整个项目,但没有区别.我的想法很新鲜.

I have verified that the dll version is the correct one, rebuilt the entire project multiple times, but no difference. I am fresh out of ideas.

推荐答案

链接 DLL 时,是否指定了/ENTRY 开关?如果是这样,它将覆盖链接器的默认设置,即 DllMainCRTStartup.因此,_CRT_INIT 不会被调用,反过来,全局初始化器也不会被调用,这将导致未初始化的全局(静态)数据.

When you linked your DLL, was the /ENTRY switch specified? If so, it'll override the linker's default which is DllMainCRTStartup. As a result, _CRT_INIT won't be called and, in turn, the global initializers won't be called which will result in uninitialized global (static) data.

如果您为自己的入口点指定/ENTRY,则需要在进程附加和进程分离期间调用 _CRT_INIT.

If you are specifying /ENTRY for your own entry point, you need to call _CRT_INIT during process attach and process detach.

如果您未指定/ENTRY,则链接器应使用 CRT 的入口点,该入口点在调用 DllMain 之前在进程附加/分离上调用 _CRT_INIT.

If you are not specifying /ENTRY, the linker should be using the CRT's entry point which calls _CRT_INIT on process attach/detach before calling into your DllMain.

这篇关于加载 DLL 不初始化静态 C++ 类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:加载 DLL 不初始化静态 C++ 类