尽管 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文件名 只有一个文件名在特定的系统中存在

dllexport 和 dllimport 有啥区别?

char** DllImport 失败

读取注册表项

在DllImport中使用Unicode字符串和用Rust编写的DLL

不一致的 dll 链接和 dllimport 静态数据成员的定义不允许