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

时间:2009-09-19 03:01:53

标签: c windows dll

是否有人知道部署本机(无COM,无.NET)ANSI C 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存根和.def文件,其中fftw分发.def文件,但不分发.lib存根和.exp文件。我想我可以直接转储那些看起来很有用的东西(或者只是反映官方zlib目前的内容),但我想知道为什么它必须存在于它所属的目录中。

是否有良好的维护Windows发行版的例子来源于unix世界?

Official zlib binary distributions (scroll down)

Our windows distributions

要澄清:

我们分发一个库并向(大多数)Windows用户提供zlib,因为他们通常没有它。我希望我们的zlib构建通常可用作组件,而不仅仅是我们的产品消耗的.dll。我们是开源的并且被广泛使用,所以我们确实希望使我们的整个构建环境可用并且很容易适应您想要使用的任何编译器。

3 个答案:

答案 0 :(得分:2)

如您所知,混合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,来自您的托管应用程序的安装,或者也包含在您的包中。可以从批处理文件运行依赖性walker,因此可以将其用作回归测试套件的一部分,以自动执行此验证。例如,在发布基于Lua的项目时,我在Makefile中从Dependency Walker运行我的最终构建,作为构建安装包的目标的一部分,并使用perl脚本检查日志以验证所使用的唯一DLL是否为其中一部分我的安装或从系统。

正如其他人所说的那样,如果您的DLL被最终用户使用而不希望与它一起开发(例如,插件到独立分发的大型应用程序),那么您需要打包的就是DLL本身(和它拥有的任何依赖项,最终用户文档,如此)。在这种情况下,您只需确保DLL使用与应用程序相同的运行时。

如果DLL是针对开发人员社区的,那么您很可能处于Lua Binaries的多版本情况中。每个分发包都包含正确构建的DLL,以及导入库(.LIB)和所有文档。对于由VS构建的DLL,它们与其他编译器的代码相关联,可以友好地包含记录实际导出名称的.DEF文件。现代MinGW实际上并不需要它,但是Borland C的用户或者除了C之外的其他语言都可以使用他们可以获得的所有帮助。

鉴于最近动态语言(例如Lua,Perl,TCL和Python)越来越受欢迎,这些语言通常很容易绑定到用C实现的库,如果你能提供绑定,那么这些用户社区也会非常感激。这些语言,以及根据“本地习惯”编制的二进制文件,用于选择CRT。

答案 1 :(得分:1)

作为参考,我想提出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.liblua5.1.dll - 您可以在编译时链接该.lib,这就是您真正需要的所有内容。

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

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

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

答案 2 :(得分:-1)

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