代码之家  ›  专栏  ›  技术社区  ›  Dana Robinson

是否有针对Windows分发本机C库的最佳实践指南?

  •  5
  • Dana Robinson  · 技术社区  · 15 年前

    有人知道部署本机(没有COM,没有.NET)ANSIC Windows共享库的最佳实践指南吗?

    我们的产品使用zlib,我们在下载页面上发布了与官方zlib页面不同的预构建二进制文件。我猜这是因为 to avoid mixing C runtimes . 官方版本是使用VC++6.0针对MSVCRT构建的,而vs.net/2005/2008将使用MSVCRT71/80/90。

    我要做的是创建VS2005/8解决方案和项目,这些解决方案和项目将为我们正确地构建zlib,并将它们分发到我们现在拥有的地方。我想仔细地做这件事,并分发一个适当有用的包,然后我还可以将它发送给zlib的馆长,以包含在他们的源代码分发中。然而,找到可靠的信息被证明是麻烦的。我有一大堆关于win32编程的书,我在网上找到了很多文章,但这些似乎都不能很好地描述你 真的? 需要分发。

    例如,zlib分发.exp、.lib stub和.def文件,其中fftw分发.def文件,而不是.lib stub和.exp文件。我想我可以把里面看起来有用的东西都扔掉(或者照一下Zlib现在的样子),但我想知道 为什么? 它必须在那里,在它所属的目录中。

    有没有源于Unix世界的、维护良好的Windows库发行版的好例子?

    Official zlib binary distributions (scroll down)

    Our windows distributions

    澄清:

    我们分发一个库,并向(主要是)Windows用户提供zlib,因为他们通常没有该库。我希望我们的zlib构建在一般情况下作为一个组件是有用的,而不仅仅是作为我们的产品使用的.dll。我们是开放源码的,并且被广泛使用,所以我们希望使整个构建环境可用,并且能够轻松地适应您想要使用的任何编译器。

    3 回复  |  直到 15 年前
        1
  •  2
  •   Community c0D3l0g1c    7 年前

    如您所知,混合C运行时是一个真正的问题。因此,DLL分布的一个维度将始终是运行时的选择。有时这不是一个自由的选择。运行时将由现有应用程序(think plugin)加载的dll必须(通常)与宿主应用程序使用的CRT的选择相匹配。

    您可能会想到,您可以静态地将CRT链接到您的DLL中,并避免这个问题。然后出现的问题是,当您必须在dll及其宿主应用程序之间传递分配的指针时,因为混合运行时的大多数问题都来自于有多个 malloc() free() 在一个过程中。然而,有了精心设计和实现的DLL API,这可能是解决方案。

    像这样的分配 Lua Binaries 通过描述 Mark Rushakoff's answer 使用大量的构建自动化来安排使平台和编译器的许多组合可用。维护构建过程对于其团队来说是相当多的工作。当一个单独的组决定创建一个 Windows installer for Lua 为了给Windows用户提供一个简单的首次使用体验,他们决定(我相信是明智的)为他们的产品选择一个CRT版本,并要求他们附带的所有扩展DLL都是根据该版本编译的。

    作为发布包的一部分,您应该遵循的一个实践是 Dependency Walker 验证是否使用了预期的CRT,以及是否所有其他依赖项都是来自宿主应用程序安装的系统DLL,或者也包含在包中。依赖关系查询器可以从批处理文件中运行,因此它可以作为回归测试套件的一部分自动进行验证。例如,在发布基于Lua的项目时,我从生成文件中运行依赖项下的最后一个构建,作为构建安装包的目标的一部分,并使用Perl脚本检查日志,以验证使用的唯一DLL是我的安装的一部分还是系统的一部分。

    正如其他人所说,如果您的dll被不希望使用它开发的最终用户使用(例如独立分布的更大应用程序的插件),那么您应该打包的只是dll本身(以及它所具有的任何依赖项、最终用户文档等)。在这种情况下,只需确保DLL使用与应用程序相同的运行时。

    如果DLL是针对开发人员社区的,那么您很可能在许多构建Lua二进制文件的情况下。每个分发包将包含正确构建的dll,以及导入库(.lib)和所有文档。对于由VS构建的DLL(这些DLL预期与其他编译器的代码相链接),可以很友好地包含.def文件,该文件记录实际导出的名称。现代明格实际上并不需要它,但是BorlandC或者其他语言的用户可以使用他们所能得到的所有帮助。

    鉴于Lua、Perl、Tcl和python等动态语言(通常可以轻松绑定到C中实现的库)最近越来越受欢迎,如果您能够提供这些语言的绑定,以及针对“本地自定义”编译的二进制文件供CRT选择,那么这些用户社区也会非常感激它。

        2
  •  1
  •   Mark Rushakoff    15 年前

    作为参考,我想提出 LuaBinaries . 简短的背景知识是,由于Lua是相当可配置的,所以他们认为有一个“标准”发行版是很好的,这样任何人都可以,例如,分发字节码编译的Lua脚本,并且任何使用“标准”Lua二进制文件的人都可以用相同的结果运行它们。

    您将在Windows部分看到下载与表单匹配 Lua_5_1_4_Win32_{PLAT}{VER}_lib.zip . plat可以是cygwin、vc[6-9]、mingw或只是dll等。

    举个例子,如果你想抓住, lua5_1_4_Win32_vc9_lib.zip 你会发现 lua5.1.lib 文件(加上头),因为这是静态库(这个库是在VS2008中编译的)。

    lua5_1_4_Win32_dll9_lib.zip 包含 Lua5.1.LIB lua5.1.dll -您可以在编译时链接到该.lib,这正是您真正需要的。

    如果您的唯一目标是Visual Studio,则在编译为dll时生成的.lib应该是除了dll和头文件之外唯一需要的文件,除非您希望用户只调用LoadLibrary和GetProcAddress来访问您的dll的所有功能。

    据我所知,.def文件的唯一需要是 interoperate DLLs between MinGW and VS . 我的理解是很久以前,vs除了使用.libs之外还使用了.def文件,但是现在vs所需的所有信息都只包含在.lib中。您可以在.lib和.def文件之间转换(如果您不能在其中一个或另一个文件上编译代码),但这有点麻烦——您必须使用 pexports 例如,生成一个.def文件。

    希望luabinaries对于如何支持现有的许多win32编译器是一个很好的参考。但我真的不确定是否有必要为每个版本的vs制作一个.lib存根,因为我很确定我已经向使用vs2008的人发送了vs2003.lib和.dll,没有问题。

        3
  •  -1
  •   Matthew Talbert    15 年前

    如果您的目标是最终用户(即,您只需要运行应用程序),则只需分发DLL。