【问题标题】:statically and dynamically linking DLLs generated with different versions of Visual Studio静态和动态链接使用不同版本的 Visual Studio 生成的 DLL
【发布时间】:2009-06-15 13:41:44
【问题描述】:
这是我正在寻找反馈的情况:
- 在工作中,我的职责之一是维护几个遗留应用程序,我们将其中一个称为“LegacyApp”。它一直是用 VS 6.0 编译的。 (而且这些天没怎么接触过。)
- 它使用提供对某些专用硬件的访问的 API。这个 API 是由我公司的另一个小组制作的。我们将此 API 称为“ControllerAPI”。它一直是用 VS 6.0 编译的。
- LegacyApp 的开发人员还围绕 ControllerAPI 编写了一个包装 DLL,LegacyApp 将使用该 DLL。我们称之为“WrapperAPI”。我负责维护这个。它一直是用 VS 6.0 编译的。
- WrapperAPI 静态链接到 ControllerAPI。
- LegacyApp 动态地针对 WrapperAPI 进行墨迹。
- 在他们的下一个版本中,制作 ControllerAPI 的小组已经开始使用 VS 2008 来编译它,而不是 VS 6.0,就像他们目前的情况一样。
所以,这是我的问题:
- 由于 WrapperAPI 与 ControllerAPI 静态链接,我需要用 VS 2008 编译 WrapperApi 吗?那是对的吗? (我已经这样做了,在这种情况下是一个简单的步骤。)
- 由于 LegacyApp 是针对 WrapperAPI 动态链接的,我可以在 VS 6.0 中继续编译 LegacyApp 吗?如果是这样,在我的 WrapperAPI 编译中我需要做些什么来确保情况仍然如此。或者我是否需要在 VS 2008 中编译旧版应用程序,我现在不想这样做。
所以,我的问题归结为相互运行已使用不同版本的 Visual Studio 编译的应用程序和 Dll,以及静态或动态链接各个层是否会有所不同。
感谢您的反馈
【问题讨论】:
标签:
visual-studio-2008
linker
【解决方案1】:
如果从 ControllerAPI 和 WrapperAPI 导出的函数的签名没有改变,那么你的绑定应该是好的,静态的或动态的。
但是,如果函数使用的类型和对象(输入、输出、返回参数)依赖于外部库;那么你可能有问题。
例如,假设 ControllerAPI 为一个版本的 C 运行时分配内存,而 WrapperAPI 期望能够自行释放它 - 那么在这种情况下,它们都需要链接到相同版本的 C 运行时.如果您在 VS2008 中重新创建项目而不是导入和升级它 - 那么您的默认编译目标和导入的库可能已更改。在使用 MFC、ATL 等已知类型创建的库中可以观察到类似问题。
很遗憾,您需要手动检查这些场景,但如果您可以检查以下项目,则应该没问题。我还应该注意,这些内容也将在任意两个给定版本的 Visual Studio 之间进行检查,甚至在针对不同编译目标或平台 SDK 版本的任意两个构建之间进行检查。
- 在任何情况下,任何一个 DLL 都不需要知道由另一个 DLL 链接的引用(内存/句柄/资源分配)。但是,如果 WrapperAPI 考虑到来自 ControllerAPI 的项目并适当地处理它们是可以的(例如,ControllerAPI 分配一些东西,WrapperAPI 使用它,然后将其交还给 ControllerAPI 以进行释放/销毁)。
- 两个 DLL 使用的结构中没有内存对齐差异。
- 已定义的参数类型没有变化。注意一个版本声明了一个 32 位类型的变量,但在 VS2008 中重新编译时,在某些编译目标 (LONG) 下可能是 64 位。
- 导出/导入 DLL 函数和任何函数参数类型的调用约定(cdecl / pascal / 等)没有变化。