我有两个控制台应用程序 A1.exe A2.exe 和一个 DLL。两者都在 Debug模式下运行,优化关闭。 有一个全局 const char* 变量,我从这个 dll 导出并导入回 A1 和 A2:
//dll.h
extern "C" {DLLEXPORT extern const char* str;}
//dll.cpp
const char *str = "qwerty123";
我希望在 DLL 的只读部分中创建“qwerty123”,并且我希望 Windows 的内存管理器会将带有此字符串的实际内存映射到 A1.exe 的某个虚拟内存地址和 A2.exe 的不同虚拟地址并且不创建数据的真实拷贝。我希望该 dll 中的所有函数定义也会发生这种情况。
我同时运行这两个应用程序,它们都打印从 DLL 导入的正确字符串。然而,我想要一些证据,所以我残酷地使用 Cheat Engine 附加到 A1.exe 进程,并将该只读字符串更改为某个不同的值。结果是 A1.exe 打印新值,而 A2.exe 仍然打印旧值。这怎么解释呢? 1. 我以为它是只读内存,它将被共享以节省实际内存,那么为什么只针对一个应用程序改变值呢? 2. 如何证明两个进程的程序代码部分(导出函数)不重复?
最佳答案
您在这里考虑的优化称为写入时复制。对于 Visual C++,DLL 中定义的所有全局变量最初都通过 PAGE_WRITECOPY 属性加载到共享内存页中。如果某个进程写入这样的位置,它会收到自己的带有 PAGE_READWRITE 属性的页面并进一步使用它。 Visual C++ 似乎对 const 和非 const 全局变量没有区别,因为该属性是编译器功能。例如,它可以通过强制转换而被丢弃,从操作系统的角度处理它会是一个令人头痛的问题,而且也是一个安全漏洞。
尝试在网络上搜索PAGE_WRITECOPY
以了解更多详细信息。
关于c++ - DLL的公共(public)只读存储器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49615133/