在Visual Studio中使用.def代替全局变量的dllimport/dllexport
Using a .def in Visual Studio instead of dllimport/dllexport with global variables
在PluginLoader.exe的main.cpp中:
int Lives = 9;
该项目还包含一个.def文件,用于导出Lives变量(已修改的c++):
EXPORTS
?Lives@@3HA
使用依赖walker,我在打开PluginLoader.exe时验证了?Lives@@3HA
确实被导出。还导出了一个.lib,其中应该包含我们可以在其他项目中链接的存根。在stub PluginLoader上使用dumpbin.exe。lib我得到:
4 ?Lives@@3HA
1 __IMPORT_DESCRIPTOR_PluginLoader
2 __NULL_IMPORT_DESCRIPTOR
4 __imp_?Lives@@3HA
3 ⌂PluginLoader_NULL_THUNK_DATA
PluginLoader正在使用LoadLibrary/GetProcAddress加载SimplePlugin.dll。SimplePlugin.dll有一个main.cpp,看起来像这样:
extern int Lives;
extern "C" __declspec(dllexport) void PluginMain()
{
++Lives;
}
SimplePlugin也链接到存根PluginLoader.lib。当尝试增加生命时,我总是因为ACCESS违例而崩溃。看起来我的SimplePlugin.dll是伪获得自己版本的Lives变量,即使它链接到存根。
如果我将ONLY SimplePlugin's Lives更改为:
__declspec(dllimport) extern int Lives;
一切正常。为什么会这样?我认为.def的目的是不必使用dllexport/dllimport。我目前的假设是,具有全局变量的dlimport在幕后做了一些诡计(&Lives
如何在dll与exe中工作?)。这和__imp_?Lives@@3HA
有关系吗?
注意:不带dllimport的导入函数指针可以正常工作。只有全局变量才会导致崩溃。这在VS 2010和2012中重现
示例项目:https://db.tt/maV0oWop
当您对数据使用dllimport
时,编译器确实生成间接代码。
原因是DLL只能导出指向导出数据的指针,而dllimport
为您解除对该指针的引用。对于函数指针,显然不需要这样做。
MS docs on the
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 当vector是tje全局变量时,c++中vector的内存管理
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 内联函数中具有内部链接的全局变量
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 全局变量 多读取器 一个写入器多线程安全?
- 如果全局变量默认是外部变量,为什么要添加"extern"关键字?
- 不同作用域中的静态变量和全局变量
- C++ 在编译时具有函数计算全局变量
- 修改程序的入口点时未调用全局变量的构造函数
- 使用 std::ios_base::Init 正确初始化全局变量
- 为什么我的全局变量似乎没有变化?
- C ++程序如何返回我的数组或写入全局变量
- 为什么我的数组值与此处的全局变量不匹配?
- QT C++中对全局变量的未定义引用
- 跨多个类的全局变量而不会出现重定义错误?
- 赋予全局变量而不是局部变量优先级的函数 - (异常行为)
- C++线程不检测全局变量更改
- 在 elf 文件中查找全局变量的位置
- 在Visual Studio中使用.def代替全局变量的dllimport/dllexport