使用MSVC

时间:2017-12-13 19:30:36

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

据我了解,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组合?否则,我应该遵循哪个领导?

背景

此模块将用于多个.dll和一个.exe链接在一起。我需要在运行时在结果进程中有一半数据的单个实例(由.dll实现,因为它只加载一次),而另一半重复到每个{{1 }}或.dll并在其中初始化(由exe实现)。

2 个答案:

答案 0 :(得分:0)

据我所知,你不能为此创建单个.lib,但是你可以使用msvc的#pragma comment(lib,)来实现同样的功能,你只需要有多个#pragma注释(lib, )一个用于动态.lib,一个用于静态。

答案 1 :(得分:0)

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

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的导入库。

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