Dll导入/导出

时间:2015-08-27 12:48:11

标签: c++ dll

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

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

我发现奇怪的部分和我认为导致LINK4217和C4273警告的部分是Foo和Bar库都包含类MyClass的标题和源文件(警告提到这个类):< / p>

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

其中BAR_API在Bar库中定义为__declspec(dllexport),而在Foo库中,__declspec(dllimport)根据:{/ p>

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

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

1 个答案:

答案 0 :(得分:2)

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

根据我的理解,正确的是:

  1. MyClass中定义Foo.dll(因为Bar.dll已经取决于它)并使用MyClass __declspec(dllexport) Foo.dll导出MyClass 1}}声明。
  2. #include头文件,在MyClass的{​​{1}}文件中声明__declspec(dllimport)(将使用Bar.dll指定为导入的头文件);但是,不要包含实现.cpp的{​​{1}}文件。
  3. .cpp(在这种情况下应该重命名为FOO_API)可以根据MyClass(在BAR_API中定义dllexportdllimport来帮助您实现此目的。这个案例应该重命名为BAR_EXPORTS)。您应该在Foo项目的每个源文件中FOO_EXPORTS通过设置编译器命令行参数或#include Foo项目中每个#define FOO_EXPORTS文件中#defines FOO_EXPORTS的公共头文件(但不是酒吧项目)。

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

    HTH