Dll导入/导出

Dll import/export

本文关键字:导出 导入 Dll      更新时间:2023-10-16

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

  • Dll项目名为Foo
  • Dll项目名为Bar(取决于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被定义为什么,而不是__declspec(dllimport)在Foo库?

让我们看看这里有什么1. 定义MyClass并导出它的Foo.dll2. Bar.dll依赖于Foo.dll,但也定义了MyClass——这是混淆链接器的模糊来源。

在我看来,正确的做法是:

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

BAR_API(在本例中应重命名为FOO_API)根据是否定义了BAR_EXPORTS(在本例中应重命名为FOO_EXPORTS),将其定义为dllexportdllimport,从而帮助您实现这一点。你应该在Foo项目的每个源文件中设置#define FOO_EXPORTS,要么通过设置编译器命令行参数,要么通过#包括Foo项目中每个.cpp文件中的#defines FOO_EXPORTS的通用头(但不是在Bar项目中)。

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

HTH