【问题标题】:Producing a hybrid static library with MSVC使用 MSVC 生成混合静态库
【发布时间】:2018-05-27 19:15:39
【问题描述】:

据我了解,Visual Studio 库项目在编译后使用两个单独的进程,具体取决于“常规/配置类型”设置:

  • 如果选择了“静态库”,所有的目标文件都会被捆绑到最终的.lib文件中,一个静态库

  • 如果选择“动态库”,则所有目标文件连同依赖项一起链接在一起,并捆绑到最终的.dll 文件中,即一个动态库。同时,收集所有__declspec(dllexport) 符号,并用于生成.lib 文件,即导入库

我想创建一个foo.lib/foo.dll 对,其中foo.lib 既是foo.dll 的导入库,又是一个静态库。我考虑了以下线索:

  • 创建两个单独的项目,FooLibFooDll,以及 use lib.exe in a post-build step to merge both .lib files。这听起来像是最简单的选择,但需要将原本应该是一个有凝聚力的模块分成两半。

  • 创建单个 DLL 项目,让默认构建过程创建 foo.dll 及其导入库。然后添加自定义构建步骤以手动收集目标文件并将它们与 lib 捆绑到导入库中。这听起来很乱,我不确定重复项会做什么。

  • 我尝试过处理.def 文件,但即使在dumpbin 生成的lib 文件之后,我也对其行为感到有些困惑。此外,它需要一个明确的损坏符号列表,这是不切实际的。

有没有更简单的方法来实现混合.lib/.dll 组合?否则,我应该遵循哪条线索?


背景

此模块将用于多个.dlls 和一个.exe 链接在一起。我需要在运行时的结果过程中有一半数据的单个实例(这是由.dll 实现的,因为它只会加载一次),而另一半复制到每个.dll 或@ 987654343@并在其中初始化(通过.lib实现)。

【问题讨论】:

  • 我其实不明白背景...你不能只是拆分你的代码,部分应该是一个项目中的静态库,而另一个项目中的动态库部分?加上运行时唯一的数据可以通过 dll 来实现!!!
  • @user1810087 你描述了第一条线索 :) 我会试着澄清最后一段。

标签: c++ visual-studio visual-c++ dll static-libraries


【解决方案1】:

据我所知,您无法为此创建单个 .lib,但是您可以使用 msvc 的 #pragma comment(lib, ) 来实现几乎相同的目的,您只需拥有多个 #pragma comment(lib, ) 一个用于动态 .lib,一个用于静态。

【讨论】:

  • 嗯,#pragma comment...如果我把它放在静态库中,这也可能是将导入库和静态库粘在一起而不诉诸lib.exe 的更好方法。跨度>
  • @Quentin:你为什么不制作一个库,然后从库中制作一个 dll?显然,它们不会在使用它们的项目中同时被引用。如果这不是您的想法,那么您就是在让自己陷入设计的死胡同。
  • @MichaëlRoy 因为他们应该有一半的数据,而不是相同的内容。
  • 一个dll的数据属于它的调用进程。虽然 dll 的多个实例(在不同的进程中)可能为其代码段共享相同的物理地址,但其数据却完全不是这样。每个进程都有自己的数据,即使它属于一个 dll。
  • 也许你真正想要的不是dll,而是全局数据提供者,也就是服务。
【解决方案2】:

我终于采取了我在问题中列出的第一条路线:创建两个项目,一个静态库和一个动态库,并合并它们的输出。这最终比预期的要容易:我只需将 DLL 的导入库注册为静态库的“Librarian”构建步骤的依赖项,并设置项目引用以获得正确的构建顺序。

FooDll.vcxproj:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <!-- snip snip snip -->
    <PropertyGroup>
        <TargetName>Foo</TargetName>
    </PropertyGroup>
    <ItemDefinitionGroup>
        <Link>
            <ImportLibrary>$(OutDir)FooDll.lib</ImportLibrary>
        </Link>
    </ItemDefinitionGroup>
    <!-- snip snip -->
</Project>

Foo.vcxproj:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <!-- snip snip snip -->
    <ItemDefinitionGroup>
        <Lib>
            <AdditionalDependencies>$(OutDir)FooDll.lib;$(AdditionalDependencies)</AdditionalDependencies>
        </Lib>
    </ItemDefinitionGroup>
    <!-- snip snip -->
    <ItemGroup>
        <ProjectReference Include="..\FooDll\FooDll.vcxproj" />
    </ItemGroup>
    <!-- snip -->
</Project>

最终结果是Foo.dll/Foo.lib 对,后者本身既是静态库,又是Foo.dll 的导入库。

我仍然需要跨越两个项目,但这很简单,我很满意。

【讨论】:

    猜你喜欢
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 2020-03-02
    • 1970-01-01
    • 2012-07-24
    相关资源
    最近更新 更多