是否有一个最佳实践指南,分发Windows本地C库?

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

我们的产品使用zlib,我们在我们的下载页面上发布与官方zlib页面不同的预构build二进制文件。 我猜测这是为了避免混合C运行时 。 官方的是使用VC ++ 6.0构build的msvcrt,VS.NET/2005/2008将使用msvcrt71 / 80/90。

我想要做的是创buildVS2005 / 8解决scheme和项目,以便为我们正确构buildzlib并将它们分发到我们现在拥有的位置。 我想仔细地做这件事,并分发一个适当的有用的包,我也可以发送给zlib的策展人包括在他们的源代码发行。 但是,find可靠的信息已经certificate很麻烦。 我有一大堆关于Win32编程的书,我在网上发现了很多文章,但是这些文章似乎都没有详细描述你真正需要发布的东西。

例如,zlib分发.exp,.lib存根和.def文件,其中fftw分发.def文件,但不分发.lib存根和.exp文件。 我想我可以把所有在那里看起来有用的东西(或者只是镜像官方的zlib),但是我想知道为什么它必须在那里以及它属于哪个目录。

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

官方zlib二进制发行版(向下滚动)

我们的Windows发行版

澄清:

我们发布一个库,并提供zlib(主要)Windows用户,因为他们通常没有它可用。 我希望我们的zlib版本能够作为一般的组件使用,而不仅仅是作为我们的产品消耗的.dll。 我们是开放源代码并被广泛使用,因此我们希望使我们的整个构build环境可用,并且可以轻松地适应任何您想要使用的编译器。

如你所知,混合C运行时是一个真正的问题。 因此,DLL分发的一个维度将永远是运行时的选择。 有时候这不是一个自由的选择。 一个现有的应用程序(think插件)在运行时加载的DLL必须(通常)匹配托管应用程序使用的CRT的选择。

你可以想象,你可以静态链接CRT到你的DLL,并避免担心。 那么出现的问题是当你必须在DLL和它的宿主应用程序之间传递分配的指针时,因为混合运行时的大部分问题来自一个进程中有多个malloc()free()的实现。 有了一个精心设计和实现的API的DLL,这可以是解决方案,但是。

Mark Rushakoff的回答中描述的像Lua Binaries这样的发行版使用了大量的构建自动化来安排如此多的平台和编译器组合。 维护构建过程对于团队来说是相当多的工作。 当一个单独的组织决定为Lua创建一个Windows安装程序来为Windows用户提供一个简单的首次使用体验时,他们决定(我相信明智的)为他们的产品选择一个CRT版本,并要求他们发布的所有扩展DLL与它是编译对单一版本。

作为发布包装的一部分,您应遵循的一个做法是使用Dependency Walker来验证是否使用了预期的CRT,并且所有其他依赖项都是系统DLL,从您的托管应用程序安装中还是包含在您的包中。 依赖Walker可以从一个批处理文件运行,因此它可以作为回归测试套件的一部分自动执行此验证。 例如,当我发布基于Lua的项目时,我在Makefile的Dependency Walker下运行我的最终版本,作为构建安装包的目标的一部分,并使用perl脚本检查日志,以验证所使用的唯一DLL是我的安装或从系统。

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

如果DLL是针对开发者社区的,那么你很可能是在Lua Binaries的多版本的情况下。 每个分发包都包含正确构建的DLL,以及导入库(.LIB)和所有文档。 对于由VS构建的DLL,这些DLL需要与来自其他编译器的代码进行链接,可以很方便地包含记录实际导出名称的.DEF文件。 现代的MinGW实际上并不需要它,但Borland C或C以外的语言的用户可以使用所有他们可以获得的帮助。

鉴于最近越来越流行的动态语言,如Lua,Perl,TCL和Python,这些语言通常可以很容易地绑定到用C语言实现的库上,如果你可以提供这些语言的绑定,以及针对CRT的“本地习惯”编译的二进制文件。

作为参考点,我想提出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文件就是在MinGW和VS之间互操作DLL 。 我的理解是,很久以前,VS除了使用.libs之外,还使用了.def文件,但现在所有的信息VS需求都只包含在.lib中。 你可以在.lib和.def文件之间进行转换(如果你不能在一个或另一个上编译代码),但是有点麻烦 – 你必须使用pexports来生成一个.def文件。

希望LuaBinaries是如何支持许多Win32编译器的很好的参考。 但我真的不知道是否有必要为VS的每个版本创建一个.lib存根,因为我敢肯定我已经发送了一个VS2003 .lib和.dll给使用VS2008的人,没有麻烦。

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