DLL的常见记忆
Common read-only memory of DLL
我有两个控制台应用程序a1.exe a2.exe和一个dll。两者都在调试模式下运行,关闭了Optmization。我从该dll导出并在A1和A2中导入的全局const char*变量:
//dll.h
extern "C" {DLLEXPORT extern const char* str;}
//dll.cpp
const char *str = "qwerty123";
我希望在DLL的只读部分中创建" qwerty123",我希望Windows的内存管理器将使用此字符串将真实内存映射到A1.exe的某些虚拟内存地址和A2.exe的不同虚拟地址并且不要创建真实的数据副本。我希望从该DLL的所有功能定义也会发生这种情况。
我同时运行两个应用程序,它们都打印从DLL导入的正确字符串。但是,我想要一些证据,因此我残酷地使用作弊引擎将其附加到A1.EXE过程中,然后将仅读取字符串更改为一些不同的值。结果是A1.EXE打印新值,A2.EXE仍然打印旧值。如何解释这个?1.我认为它是仅读取的内存,并且将共享以保存真实内存,所以为什么仅对一个应用程序更改值?2.我如何获得证据表明,带有程序代码(导出功能(的部分都不重复两个过程?
您在此处考虑的优化在写入时称为复制。在Visual C 的情况下,DLL中定义的所有全局变量最初都加载在带有PAGE_WRITECOPY
属性的共享存储页面中。如果某个过程将其写入这样的位置,则它将带有PAGE_READWRITE
属性的页面并进一步使用。Visual C 似乎在const和非const全局变量之间没有区别,因为该属性是编译器功能。例如,它可以用铸件扔掉,并从OS的角度处理它也会是头痛和安全孔。
尝试搜索PAGE_WRITECOPY
的网络以了解更多详细信息。
'仅读取内存'的概念在很大程度上不适合此讨论。是的,操作系统具有使某些内存区域显示为仅阅读程序的方法,但是a(此内存完全是真实的,就像任何其他内存一样,b(b(字符串的字体并未存储在任何此类内存中无论如何。
当您将字符串声明为const
时,您只会阻止自己从C 程序中更改它,并且您可能还可以启用某些编译器的优化,尽管由于您在故障排除时正确地将其关闭,但它们不会播放任何内容在讨论中的角色。为了证明我在说什么,您可以抛弃该char*
指针的构成,然后您可以很好地修改它指向的字符串。
DLL的每个实例都有其自己的数据段。DLL实例不共享他们的数据。因此,当然,当您修改项目时,您仅在DLL的一个实例的数据段中修改它,而另一个DLL实例的数据段保持不变。
为了共享数据,您需要使用VirtualAllocEx()
和WriteProcessMemory()
,或者更好的是CreateFileMapping()
和MapViewOfFile[Ex]()
或其他一些机制。
对于连接DLL的过程,DLL的'读取全局变量'的值可能有所不同。因此,如果DLL共享多个过程的"仅读取全局变量"的单个物理内存,则是不安全的。谨慎但安全的解决方案是为多个过程创建"仅读取全局变量"的不同CTC的物理记忆实例。
例如,在dll.cpp中,
int foo(){return 1;}
typedef int (*C_pFunc)();
const C_pFunc pf=foo;
显然,A.Exe和B.Exe都加载DLL的DLL,DLL中的function foo((在A.EXE和B.EXE中可能具有不同的逻辑地址。因此,全局const变量PF在A.EXE和B.EXE中可能具有不同的初始化值。
。这是com dll的典型现象,当将com dll附加到一个过程中时,许多vtables作为全局const变量应使用此过程中的函数逻辑地址初始化。
- 松弛原子与无同步情况下的记忆连贯性
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 递归函数有效,但无法记忆
- 如何将记忆应用于此递归函数?
- C++如何在向量中查找最常见的元素
- Printf 命令不打印时添加了查找常见除数的新代码
- 共享记忆:让我们谈谈它的特殊性
- 如何从向量或数组中选择最常见的数字?(前五名)C++
- 为什么nlohmann不释放记忆
- CPP 中的瓦尔格林德和记忆泄漏:"Conditional jump or move depends on uninitialised values"
- 打印二叉树中的常见元素
- C++17 多态记忆资源不起作用
- 我是否漏了记忆?
- 关于记忆后这种递归关系的时间复杂度
- 记忆栅栏和记忆屏障是一样的吗
- 是否存在用于 C 或 C++ 中常见数学运算(例如最小值、最大值和平均值)的可导入库?
- 在 C++ 的自定义运算符中删除与删除[](不同于常见的删除与删除[]问题)
- 使用记忆在 C++ 中实现 Knapstack
- 如何从文本文件中查找最常见的字母和出现次数?
- DLL的常见记忆