如何在不需要LIBCD.lib的情况下在Visual Studio 6中编译C项目

How do I compile a C project in Visual Studio 6 without it needing LIBCD.lib?

本文关键字:Studio 项目 Visual 编译 情况下 不需要 LIBCD lib      更新时间:2023-10-16

我已经编译了VolPack(https://graphics.stanford.edu/software/volpack/)作为Visual Studio 6(在Windows XP下)中的静态库,因为我认为这就是它的用途,它不会在Visual Studio 2019下编译。但试图在Visual Studio 2019中编写C++程序并链接到volpack.lib时,我收到了错误:错误LNK1104无法打开文件"LIBCD.lib">

(我不认为这是VolPack特有的错误,我认为它适用于在VC 6下编译的任何lib,然后在VS的后期版本中链接到,所以我认为这个问题对StackOverflow来说并不太具体。)

我发现:https://support.microsoft.com/en-us/help/154753/description-of-the-default-c-and-c-libraries-that-a-program-will-link,这解释了它为什么使用这个lib,但我不知道在VS 6中该怎么办。我没有看到关于多线程的选项可以更改为使用不同的库,快速谷歌搜索显示VS6不支持多线程。

我确实发现了这一点:如何解决"无法打开文件';LIBCD.lib'"在visualstudio 2008?,但我不确定这个解决方案是否与我的问题相关,因为字符串"GLUI"在我试图链接到的库中没有出现。即使它是我问题的解决方案,我也不知道从哪里获得GLUI的源代码,我需要对makefile做什么更改,或者如何使VS 6使用新的重新编译的GLUI,不管是什么。

下一个解决方案基本上是告诉链接器忽略LIBCD.lib,但这会给我带来其他错误。我发现:https://www.youtube.com/watch?v=zKrggjsgQx4,基本上说忽略LIBCD.lib,然后将运行库更改为多线程调试,但这也给我带来了错误。

我在VS 2019下编译VolPack时遇到的错误都是"潜在的单元化本地指针变量",所以在VS 2019中编译它可能需要一些简单的修改,但我不是C语言专家,我不想处理如何修改程序和可能破坏程序的头痛问题。因此,如果有人知道一个简单的方法来解决这个问题,可能也会奏效。谢谢

当您使用一个依赖于其他库的静态库时,如果找不到其他库,编译器就会抱怨。

Microsoft Visual Studio 6.x和Visual Studio 2019之间的差异是巨大的。由于微软在遵守标准以及支持新版本的标准方面有所改进,其中一些标准摒弃了以前支持的结构,因此我不得不对6.x到VS 2015的旧代码(包括C和C++)进行了一些源代码更改,以允许编译工作。

请参阅这篇关于Visual Studio版本间兼容性、库ABI版本间兼容性的文章另请参阅:

VS2017和VS2015 之间的二进制兼容性

ABI visual studio c库的兼容性

这篇来自微软的关于2019年Visual Studio发布的博客文章写道:

Visual Studio 2019版本16.0现已提供,并且与二进制兼容VS 2015/2017。在VS 2019的首次发布中,我们实现了C++20工作文件中的更多编译器和库功能,实现了更多的重载(C++17的"最终老板"),以及修复了许多正确性、性能和吞吐量问题。这是一个C++17/20编译器/库特性工作和库列表修复。(和往常一样,许多编译器错误也得到了修复,但它们并没有此处列出;编译器修复往往特定于某些晦涩的代码图案。我们最近写了一篇关于编译器优化和构建的博客VS 2019的吞吐量改进,我们维护了一份文档关于VS 2019中编译器一致性改进的页面。)

除了使用源代码使其与Visual Studio 2019兼容之外,我看不到任何其他途径。如果你仔细观察,你可能会发现你在C方面的专业水平足以实施下面的一些建议。

最好的做法似乎是对库进行必要的源代码更改,以便在Visual Studio 2019下正确编译。

最好的做法是查看发现未初始化指针错误的每个地方的源代码,并更正源代码,使错误不再生成。以前在这些代码领域工作过的程序员显然忽略了潜在的控制流,这可能是因为他们预计,基于对如何使用函数的假设,丢失的代码永远不会被执行。最有可能的是,任何这样的函数都很复杂,可能需要重构。

我经常看到这种类型的丢失流是由于switch语句缺少default:来捕获switch变量不是指定事例值之一的事件。也可能是由于if语句是一系列else if而没有最终的else来捕获任何其他可能的条件。或者也可能是由于在初始化指针变量之前有break语句的循环,或者使用continue语句跳过变量初始化的地方。

在大多数情况下,这些问题是由于内聚性低的功能和/或过于复杂和庞大,随着时间的推移,维护操作会引入这些类型的问题。

对于可能未初始化的指针的错误,一种不太理想的做法是只使用一些适当的值进行初始化。您可以跳到错误所在的位置,单击变量并转到定义它的位置,然后将其设置为适当的值。在大多数情况下,指针的值NULL是最安全的,因为如果它保持NULL并且在未修改为正确值的情况下使用,则应用程序应该崩溃,让您知道存在问题。

通过初始化到NULL,您假设以前的程序员知道他们在做什么,并且由于逻辑的原因,编译器检测到的将变量保持为正确值不变的可能流永远不会发生。

如果发生未初始化的指针流,您将发现应用程序何时崩溃。不幸的是,要追溯这次事故的起因可能很困难。

如果是C++,则可以在代码中使用assert和其他测试来创建断点,或者生成异常,这可能比崩溃更具信息性。因此,在生成错误的源代码行之前添加这样的测试,在使用指针之前检查测试中的NULL可能会有所帮助。

或者,如果函数有一个状态代码,指示它是否工作,以及任何错误以及返回错误状态的某种方式,那么最有效的方法是在健全性检查失败时,在生成潜在未初始化指针错误的指针处使用错误报告。

但是,如果您能够识别出一个安全的默认值,您可能需要使用它。识别安全值需要查看源代码,以确定安全默认值应该是什么。有时,这样的安全值可以是初始化为零的适当类型的变量的地址。

警告:如果要返回指针中的地址,请不要使用函数本地变量的地址。当函数返回时,该地址将不再有效,从而导致"未定义的行为"。

警告2:如果指针中的地址预期是使用malloc()new或类似的内存分配器分配的,则必须使用相同的机制,以便当某些代码决定使用free()delete解除分配内存时,它将起作用。

如果指针的值本地化为函数本身,则此审查将需要读取使用未初始化指针的函数的源代码。如果指针是由函数返回的,即函数导出给函数用户的值,那么您还需要查看使用该函数的源代码,以确定适当的默认值。

所以我建议你做的是,在每个初始化的地方,您在行中添加了一个唯一的标识注释(类似于"Inhahe修复未初始化指针错误06/10/2020"的内容),这样您就可以在以后进行搜索以找到这些注释,然后返回到有问题的代码中,通过重构或更改代码来实际修复编译器错误,以消除可能的未初始化指针误差。

在你做任何事情之前,把源代码置于某种版本控制之下。

虽然如果X64版本可以与旧的32位VS6.0版本链接会很好,但我认为这将是一条艰难的道路。

我相信最好的希望是把你的WinXP代码重新定位到VS2019。在过去的几年里,我不得不做很多这样的事情
有一个一次性升级路径,您只需在其中阅读VS6.0工作区,它就会构建一组新的项目文件和SLN文件。

我对此的阅读使我相信VS6->VSnew是在VS2008时间帧中完成的;打破变化";在"C++"和MSBUILD环境中,但您可以在其中生存下来,并通过微小的更改获得可构建的代码。

我发现的一个问题是自定义构建步骤。任何带有路径的自定义生成步骤都需要目录的尾部斜杠,而任何带有引号的自定义生成过程都可能被破坏,导致您的生成挂在VS2013/VS2019中。(我在这方面的工作是VS2013)。代码的主要问题可能是for循环。旧的MS编译器允许在for循环中声明的变量范围在预期范围之外持续存在。有一个编译器开关可以解决这个问题。

我记得平台工具集V142不支持XP系统,如果你需要针对Win32操作系统,那么你必须对这些二进制文件使用V141_XP,否则源代码应该使用最新的平台工具集V142作为现代windows的x64构建。我已经成功地将一吨VS6.0用户程序迁移到VS2013和现在的VS2019,但没有什么问题。

有一个WIN32#定义可以将其保留为遗留版本,并且不会破坏x64内部版本。

在VS6.0中还有一个罕见的编译器错误;字符串池";其中生成的程序集将优化掉2个不同的字符串,就好像它们是相同的一样。字符串池与";用于执行和继续的程序数据库";这会在后台触发字符串池选项。所以我总是把这个改成";程序数据库";,因为我从来没有看到过对此的错误修复,并怀疑它可能仍在代码中。这个虫子够讨厌的,够难的,几年后我发现我仍然对枪很害羞。

谷歌在C中的突破性变化。但通常现代编译器会执行1998年甚至没有定义的东西。我在编译时发现了许多错误,这些错误在VS6.0中被跳过/忽略了。

我会一次处理一个CPP模块,看看第一个错误,然后往下走。然后,你正在使用的这个漂亮的图书馆将有一个新的生命。