【发布时间】:2011-05-09 10:56:03
【问题描述】:
我的问题是:
是否可以链接到VS2008 使用VS2010生成的DLL?
如果不是,为什么看起来是 可以链接到静态库 由VS2008生成。
我看到VS2010现在有一个平台 工具集选项。但这会让 人们将其设置为 v90 而不是 v100 即使他们没有 VS2008 安装了吗?
即使我使用 /Z7 编译器 switch,为什么我还需要一个 .pdb 用于调试 DLL。
细节
我可以使用 Visual Studio 2010 毫无问题地链接到我的由 Visual Studio 2008 生成的 Leptonica C 静态库。 (有关我如何构建 Leptonica 并链接到它的详细信息,请参阅下面的参考资料部分。)
但是,当我尝试将同一程序 (leptonlib-1.67\prog\ioformats_reg.c) 与我的 VS2008 生成的 Leptonica DLL 版本链接时,程序崩溃了。调试一下,可以看出问题是ioformats_reg.c是这样做的:
fp = fopen(filename, "rb"); /* in ioformats_reg.c */
此后不久,在 leptonlib.dll 中执行以下操作导致崩溃:
rewind(fp); /* in leptonlib.dll */
How to link with the correct C Run-Time (CRT) library 说:
一个可重用的库及其所有 用户应该使用相同的 CRT 库 类型,因此是相同的编译器 切换...
如果您确实选择混合 CRT 库, 记住你有两个分开的 CRT 的副本,带有单独的和 不同的州,所以你必须是 小心你尝试做的事情 跨越 CRT 边界。有许多 两个惹麻烦的方法 阴极射线管。这里只是一些:
- 有两个独立的堆。你不能分配(明确地用新的, malloc,等等 - 或隐含 strdup、strstreambuf::str 等), 然后将指针传递给 CRT 边界将被释放。
- 您不能通过 CRT 边界传递 FILE* 或文件句柄,并且 期望“stdio 低级 IO” 工作。
- 您不能在一个中设置语言环境并期望设置另一个语言环境。
从 Visual C++ 4.0 开始, 链接器将发出警告 (LNK4098) 如果生成的模块试图 合并多个 CRT 副本 图书馆。欲了解更多信息,请搜索 LNK4098 的帮助文件。
但我确实没有从 VS2010 链接器收到任何 LNK4098 错误消息。
Leptonica 使用 fopen()、rewind()、fclose() 等,文档将其归类为 Stream I/O 而不是“低级 IO”,但它们确实传递了 FILE ptrs。我想这就是微软所说的“stdio low-level IO”的意思。
/MD, /MT, /LD (Use Run-Time Library) 说:
传递给给定调用的所有模块 链接器必须使用相同的运行时编译 库编译器选项(/MD、/MT、/LD)。
它没有说所有模块都必须由相同版本的编译器编译。我确实对我的所有模块始终正确地使用 /MD(或 /MDd)。
在使用 DLL 时,似乎 DLL 不仅必须使用相同的 /MD 开关,而且还必须由 VS2010 编译?
我的测试用例似乎表明与 VS2008 生成的静态库的链接是可行的,但也许我只是走运了?为什么在使用 VS2010 时链接到 VS2008 生成的静态库有效,而链接到 VS2008 生成的 DLL 则无效?
这是否意味着我需要提供单独的 DLL 供 VS2008 和 VS2010 用户使用?
那么新的平台工具集选项呢?即使没有 VS2008,VS2010 用户也可以将其更改为 v900 吗?如果是这样,那么我可以告诉人们为我的 Leptonlib-1.67 项目更改该设置。
最后,我在创建库时使用了 /Z7 开关。 /Z7, /Zi, /ZI (Debug Information Format) 的文档指出:
/Z7
生成一个包含完整符号的 .obj 文件 用于调试器的调试信息。 符号调试信息包括名称 和变量的类型,以及函数和行 数字。不生成 .pdb 文件。
对于第三方库的分销商,有 没有 .pdb 文件的优势。然而 预编译头文件的 .obj 文件是必需的 在链接阶段和调试。如果只有 在 .pch 目标文件中输入信息(没有代码), 你还必须编译 /Yl(为调试库注入 PCH 参考)。
我没有使用任何预编译的头文件。但是,只有当我有可用的 .pdb 时,我才能调试我的 Leptonica DLL。即使它说“没有生成 .pdb 文件”。 .pdb 实际上是使用我当前的项目设置生成的。在我的链接器选项中包含 /PDB 是否会以某种方式覆盖在编译时指定 /Z7?
编辑:另外我应该提一下,即使没有任何 PDB,我也能够调试 Leptonica 的静态库版本。
参考文献
Leptonica 是 Dan Bloomberg 的开源 C 图像处理库,地址为 http://www.leptonica.com。我提供了使用 VS2008/VS2010 构建 Leptonica 的说明,还提供了 windows 二进制文件。
有关我如何构建 Leptonica 库的详细信息,请参阅 http://leptonica.com/vs2008doc/building-leptonlib.html 和 http://leptonica.com/vs2008doc/building-image-libraries.html。 http://www.leptonica.org/vs2008doc/building-prog-dir.html 讨论我如何链接 ioformats_reg。
我的 Leptonica VS2008 解决方案可在http://www.leptonica.com/source/vs2008-1.67.zip 获得。我的二进制库位于http://leptonica.com/source/leptonica-1.67-win32-lib-include-dirs.zip 的zip 文件中。 Leptonica 的来源是http://www.leptonica.com/source/leptonlib-1.67.tar.gz
【问题讨论】:
标签: visual-studio-2008 visual-studio-2010 visual-c++ dll linker