【问题标题】:Embarcadero C++Builder: Separate debug/release DLL references possible?Embarcadero C++Builder:可以单独调试/发布 DLL 引用吗?
【发布时间】:2015-08-24 15:17:37
【问题描述】:

根据我的主要可执行文件的构建类型(调试、发布),我想链接到我的 DLL 的匹配构建。使用 C++Builder IDE 完成此任务的正确方法是什么?

详细信息:我正在使用 Embarcadero C++Builder XE8(试用版,BCC64)。我的软件由一个可执行文件和多个库(.dll,Dynamic-link Library)在程序启动期间(而不是在运行时)加载。每个库和可执行文件都有自己的项目,所有项目都在同一个项目组中。

为了在消费项目中使用已编译的库,我已将import files of the compiled DLLs(BCC64 的.a)添加到消费项目中。

SerialPort.cbproj 节选:

<LibFiles Include="..\..\Win64\Debug\Logger.a" Condition="'$(Platform)'=='Win64'">
    <BuildOrder>3</BuildOrder>
    <IgnorePath>true</IgnorePath>
</LibFiles>

不幸的是,.dll/.a 文件的输出路径取决于变量 $(Platform) 和 $(Config),因此这些文件的路径在调试和发布版本之间有所不同。 IDE 不允许(!?)指定用于调试和发布版本的不同 DLL 文件。

我宁愿不采用丑陋的技巧,例如将生成的用于调试和发布模式的二进制文件放在同一个文件夹中,只是为了为两个构建提供一个导入文件的单一路径。 以下解决方法似乎有效,但在保存项目时被 C++Builder 覆盖:

<LibFiles Include="..\..\Win64\Debug\Logger.a" Condition="('$(Platform)'=='Win64') And ('$(Config)'=='Debug')">
    <BuildOrder>3</BuildOrder>
    <IgnorePath>true</IgnorePath>
</LibFiles>
<LibFiles Include="..\..\Win64\Release\Logger.a" Condition="('$(Platform)'=='Win64') And ('$(Config)'=='Release')">
    <BuildOrder>3</BuildOrder>
    <IgnorePath>true</IgnorePath>
</LibFiles>

有没有一种理智的方法来解决这个问题?

【问题讨论】:

  • 我可能是错的,但我知道当您在调试模式下编译 .exe 时,它​​会查看调试路径,而当您在发布模式下编译时,它会查看发布路径。它不是为你做的吗?
  • 一个EXE项目也有$(Platform)$(Config)变量。因此,如果 DLL、它们的导入 LIB 和 EXE 都基于构建配置编译到同一个文件夹中,那么只要 DLL/LIB 对每个配置使用相同的文件名,一切都应该正常工作。
  • 我有 (!?) 指定要在消费项目中使用的 .a 文件。因此,当 dll 和 exe 在构建后最终在同一目录中时,它并没有帮助。
  • 您可以使用#pragma link 宏,而不是直接将库添加到项目中。这样你就可以通过一个简单的#define 来控制它,你可以在项目配置中指定它。
  • @RodrigoGómez:谢谢,这是一个非常有用的解决方法。在提出更好的解决方案之前,我会继续这样做。

标签: c++ dll c++builder


【解决方案1】:

如 cmets 所述,一种可能的解决方案是:

您可以在其中一个源文件中使用#pragma link 指令来链接它们,而不是将 lib/a 文件添加到项目中。您可以用#ifdef 指令将其包围,以控制在哪些条件下链接哪些文件,您可以在项目选项中定义。

类似:

#ifdef DEBUG
  #pragma link "mydebulib.a"
#else
  #pragma link "myreleaselib.a"
#endif

【讨论】:

  • 实际上,在我的情况下,调试和发布的文件名是相同的。使用 $(PLATFORM) 和 $(CONFIG) 指定消费项目的库路径会自动选择正确的版本。
  • 太好了,所以,类似:#pragma link "$(PLATFORM)\$(CONFIG)\MyLib.a" 工作正常吗?
  • 不,只是#pragma link "MyLib.a"。库路径本身必须在项目选项中指定,其中可以使用 $(PLATFORM) 和 $(CONFIG)。
【解决方案2】:

每个库和可执行文件都有自己的项目,所有项目都在同一个项目组中

我会选择:

#pragma comment(lib, "Logger")

这样,如果您更改库中的某些内容,然后尝试构建可执行文件,C++Builder 会自动重新构建 Logger.apragma link 不会发生这种情况)。

还要考虑#pragma link / #pragma comment 语句中命名的文件不应包含文件扩展名。编译器将附加适当的:.lib,当目标为Win32/.a,然后目标Win64

如前所述,库路径本身可以在项目选项中指定,其中可以使用$(PLATFORM)$(CONFIG)


注意 C++Builder 10.3 Rio Release 2 需要hotfix,或者在某些情况下,在 IDE 中修改文件,然后制作或编译项目不会构建修改后的文件到生成的二进制文件中(请参阅RSP-25525Embarcadero Blog 了解更多详细信息)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 2012-06-24
    • 1970-01-01
    相关资源
    最近更新 更多