【问题标题】:Dll import/exportDLL导入/导出
【发布时间】:2015-08-27 12:48:10
【问题描述】:

我继承了一个需要移植到 Windows 和 Visual Studio 的 Linux 项目。我已经设置了与 Linux 中相同的项目结构,但我发现结构有点奇怪(也许在 Linux 中一切都很好),我相信这就是导致 LNK4217 的原因(在函数'function 中导入的本地定义的符号'symbol' ') 和 C4273 ('function' : 不一致的 DLL 链接) 警告我收到。我想要一些关于如何重新构建项目或更改代码以避免这些警告的建议。基本上这就是我所拥有的:

  • 名为 Foo 的 Dll 项目
  • 名为 Bar 的 Dll 项目(取决于 Foo dll)

我觉得奇怪并且我认为导致 LINK4217 和 C4273 警告的部分是 Foo 和 Bar 库都包含 MyClass 类的头文件和源文件(警告提到这个类):

//MyClass.h
class BAR_API MyClass
{
    //Methods etc.
}

BAR_API 在 Bar 库中定义为 __declspec(dllexport),而在 Foo 库中定义为 __declspec(dllimport),根据:

#ifdef BAR_EXPORTS
#define BAR_API __declspec(dllexport)
#else
#define BAR_API __declspec(dllimport)
#endif

你建议我如何改变这个?将 MyClass 移动到它自己的库并让 Foo 和 Bar 包含它或更改以将 BAR_API 定义为空而不是 Foo 库中的 __declspec(dllimport) 是否有帮助?

【问题讨论】:

  • 所以 Bar 依赖于 Foo... 但 Foo 使用 Bar 的 MyClass? MyClass 应该定义一次(如果需要,在第三个项目中)。
  • 是的,但是由于现在已设置解决方案,因此 Foo 不需要从 Bar 导入,因为它还包含 MyClass 的头文件和源文件。但我猜 Foo 试图导入它,因为 BAR_API 被定义为 __declspec(dllimport)。
  • 基本上,我只会在 Foo.dll 项目中保留一个 MyClass 版本(包括头文件和源代码)(应该使用类似的 FOO_API 导出)。然后,您应该包含来自 Bar 的标头并将 Bar 与 Foo.lib(Foo 的导入库)链接。
  • 构建 Bar 时会得到 LNK4217,但 BAR_EXPORTS 不是#defined。它看到类的 dllimport 但无论如何都发现了类的定义,这不是很高兴。 C4273 大体相同。

标签: c++ dll


【解决方案1】:

让我们看看你有什么 1. Foo.dll 定义 MyClass 并将其导出 2. Bar.dll 依赖于 Foo.dll,但也定义了 MyClass - 这是混淆链接器的歧义来源。

据我了解,正确的做法是:

  1. Foo.dll 中定义MyClass(因为Bar.dll 已经依赖它)并在Foo.dllMyClass 声明中使用__declspec(dllexport) 导出MyClass
  2. #include 头文件,在 Bar.dll.cpp 文件中的适当位置声明 MyClass(其中将使用 __declspec(dllimport) 指定为导入);但是,不要包含实现MyClass.cpp 文件。

BAR_API(在这种情况下应该重命名为 FOO_API)通过定义为 dllexportdllimport 来帮助您实现这一点,具体取决于 BAR_EXPORTS(在这种情况下应该重命名为 @987654344) @) 被定义为。您应该在 Foo 项目中的每个源文件中使用 #define FOO_EXPORTS,方法是设置编译器命令行参数,或者通过在 Foo 项目中的每个 .cpp 文件中包含 #defines FOO_EXPORTS 的公共头文件(但不是在 Bar 项目中)。

这样 Foo.dll 和 Bar.dll 都将使用 Foo.dll 中的 MyClass。

HTH

【讨论】:

  • 实际上是 Bar.dll 导出了 MyClass,因为 MyClass 头文件和源文件与 Bar.dll 的源代码的其余部分位于同一位置。但我想我还是可以做出你提议的改变。
  • 如果您不想引入循环依赖,并保留 Bar.dll 对 Foo.dll 的依赖,则需要将类放在 Foo 中,或者将其放在两者中避免导出/导入它
猜你喜欢
  • 1970-01-01
  • 2012-12-20
  • 1970-01-01
  • 1970-01-01
  • 2011-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-07
相关资源
最近更新 更多