尽管 dllimport 在两个 DLL 中导出的数据符号
Posted
技术标签:
【中文标题】尽管 dllimport 在两个 DLL 中导出的数据符号【英文标题】:Data symbol exported in both DLLs despite dllimport 【发布时间】:2009-09-24 09:56:57 【问题描述】:我有一个关于在 DLL 中导出/导入全局变量的问题。我有一个包含全局变量的静态库,例如:
在标题中:
#ifdef _ENGINE_EXPORTS
extern __declspec(dllexport) Globals data;
#else
extern __declspec(dllimport) Globals data;
#endif
在源文件中:
#ifdef _ENGINE_EXPORTS
__declspec(dllexport) Globals data;
#else
__declspec(dllimport) Globals data;
#endif
这个全局变量被导出到一个链接到这个静态库的 DLL 中。我可以使用 DLL Export Viewer 查看导出的符号。我的问题是我想在另一个 DLL 中使用这个全局变量并且它们共享数据。现在,同样的符号也在 DLL 中导出(我也可以看到),因此它们具有不同的地址。我希望在另一个 DLL 中,全局变量与第一个 DLL 中的相同。
谢谢。
【问题讨论】:
【参考方案1】:以下 MSDN 文档主题描述了如何将数据放入共享段中:How do I share data in my DLL with an application or with other DLLs?
【讨论】:
我找到了这个页面,但我想要一个简单的解决方案。【参考方案2】:在项目中,一个 DLL 位于所有其他 DLL 的根目录中,因此我将符号导出到这个 DLL 中,它似乎可以工作。
【讨论】:
【参考方案3】:根据您的描述,我了解到您有两个不同的 DLL,它们都导出全局变量 data
。
当一个 DLL 导出一个变量时,该 DLL 为该变量的内容分配内存,并通过变量名向同一进程中的其他软件部件(例如加载该 DLL 的应用程序)提供使用该内存。因此,如果您从两个 DLL 中导出 data
,则两个 DLL 都会分配内存,并且都在其上下文中提供变量名称 data
(您可以将其想象为具有相同名称但位于不同命名空间中的两个变量)。
您想要做的是,一个 DLL 导出 data
而另一个 DLL 导入此变量。有了这个 (dllimport
),您可以声明变量名而不定义(因此不为其分配内存)。
因此,从您的问题中获取这个静态库作为 static.hpp、static.cpp 和 static.lib:
你有 dll_1.cpp(链接到 static.lib)
#define _ENGINE_EXPORTS (1)
#include "static.h"
__declspec(dllexport) int getAdrAsInt_1()
return (int)&data;
和dll_2.cpp(链接到dll_1的“导入库”,见here)
// here without _ENGINE_EXPORTS to use dllimport instead of dllexport
#include "static.h"
__declspec(dllexport) int getAdrAsInt_2()
return (int)&data;
从 dll_2 访问 dll_1 中数据的另一种方法是从 dll_2 使用 GetProcAddress。但是,您需要来自 LoadLibrary 调用的 HMODULE
来加载 dll_1。
顺便说一句:据我了解,您的情况“How do I share data in my DLL with an application or with other DLLs?”不适用,因为它描述了一个完全不同的场景。
【讨论】:
以上是关于尽管 dllimport 在两个 DLL 中导出的数据符号的主要内容,如果未能解决你的问题,请参考以下文章
C# 如何判断DllImport()所引用的dll文件是不是存在 我有两个dll文件名 只有一个文件名在特定的系统中存在