如何在不需要 LIBCD.lib 的情况下在 Visual Studio 6 中编译 C 项目?
How do I compile a C project in Visual Studio 6 without it needing LIBCD.lib?
我在 Visual Studio 6(在 Windows XP 下)中将 VolPack (https://graphics.stanford.edu/software/volpack/) 编译为静态库,因为我认为这就是它的目的,它不会' t 在 Visual Studio 2019 下编译。但是尝试在 Visual Studio 2019 和 link 到 volpack.lib 中编写 C++ 程序我得到错误:错误 LNK1104 无法打开文件 'LIBCD.lib'
(我不认为这是 VolPack 特有的错误,我认为它适用于在 VC 6 下编译的任何库,然后 linked 到更高版本的 VS,所以我认为这个问题对于 Whosebug 来说并不太具体。)
我发现了这个:https://support.microsoft.com/en-us/help/154753/description-of-the-default-c-and-c-libraries-that-a-program-will-link,这解释了为什么它使用该库,但我不知道在 VS 6 中如何处理它。我没有看到关于多线程的选项更改为让它使用不同的库,快速 Google 搜索显示 VS 6 不支持多线程。
我确实找到了这个:How to solve "cannot open file 'LIBCD.lib' " in visual studio 2008?,但我不确定该解决方案是否与我的问题相关,因为字符串 "GLUI" 在我尝试 [=39 的库中没有出现=] 到。即使它是我的问题的解决方案,我也不知道从哪里获得 GLUI 的源代码,我到底需要对 makefile 进行哪些更改,或者如何使 VS 6 使用新的重新编译的 GLUI,无论如何.
下一个解决方案基本上是告诉 linker 忽略 LIBCD.lib,但这给了我其他错误。我发现了这个:https://www.youtube.com/watch?v=zKrggjsgQx4,它基本上是说要忽略 LIBCD.lib,然后将运行时库更改为多线程调试,但这也给了我错误。
我尝试在 VS 2019 下编译 VolPack 时遇到的错误都是 "potentially unitialized local pointer variable",因此可能需要一些简单的修改才能使其在 VS 2019 下编译,但我不是 C 和我不想处理试图弄清楚如何修改程序和可能破坏程序的头痛。所以任何人都知道解决该问题的简单方法也可能有效。谢谢。
当您使用依赖于其他库的静态库时,如果编译器找不到那些其他库,它就会报错。
Microsoft Visual Studio 6.x 和 Visual Studio 2019 之间的差异是巨大的。由于我已经将旧代码(C 和 C++)从 6.x 移植到 VS 2015,因此由于 Microsoft 在遵守标准方面的改进,我不得不对源代码进行一些更改以允许编译工作以及支持新版本的标准,其中一些标准弃用了以前支持的结构。
查看此 post 关于版本之间的兼容性,Library ABI compatibility between versions of Visual Studio
另见:
ABI-Compatibility of visual studio c-libraries
而这张 blog posting from Microsoft about the release of Visual Studio 2019 日期为 2019 年的文章说:
Visual Studio 2019 version 16.0 is now available and is binary compatible
with VS 2015/2017. In this first release of VS 2019, we’ve implemented
more compiler and library features from the C++20 Working Paper,
implemented more overloads (C++17’s “final boss”), and
fixed many correctness, performance, and throughput issues. Here’s a
list of the C++17/20 compiler/library feature work and the library
fixes. (As usual, many compiler bugs were also fixed, but they aren’t
listed here; compiler fixes tend to be specific to certain arcane code
patterns. We recently blogged about compiler optimization and build
throughput improvements in VS 2019, and we maintain a documentation
page about compiler conformance improvements in VS 2019.)
除了使用源代码使其与 Visual Studio 2019 兼容之外,我没有看到任何其他资源。如果你看,你可能会发现你对 C 的专业水平足以实现以下是一些建议。
最好的做法似乎是对库进行必要的源代码更改,以便它可以在 Visual Studio 2019 下正确编译。
最好的做法是在每个发现未初始化指针错误的地方检查源代码并更正源代码,以便不再产生错误。以前在这些代码区域工作的程序员显然遗漏了潜在的控制流,这可能是因为他们期望根据函数的使用方式假设永远不会执行丢失的代码。很可能任何此类功能都很复杂,可能需要重构。
我经常看到这种类型的缺失流是由于 switch
语句缺少 default:
来捕获 switch
变量不是指定变量之一的事件案例值。也可能是由于 if
语句是一系列 else if
而没有最终的 else
来捕获任何其他可能的条件。或者它也可能是由于循环在初始化指针变量之前有一个 break
语句或者使用 continue
语句跳过变量初始化的地方。
在大多数情况下,这些问题是由于低内聚的函数 and/or 过于复杂和庞大,随着时间的推移引入此类问题的维护操作。
对于可能未初始化的指针的错误,一个不太理想的做法是只用一些适当的值进行初始化。可以跳转到错误的地方,点击变量然后到它定义的地方,然后给它设置一个合适的值。在大多数情况下,指针的值 NULL
是最安全的,因为如果它保持 NULL
并且在未修改为正确值的情况下使用,您的应用程序应该崩溃,让您知道存在问题。
通过初始化为 NULL
,您假设以前的程序员知道他们在做什么,并且编译器检测到的可能的流程将永远不会发生将变量保持不变为正确值的情况,因为逻辑。
如果发生未初始化的指针流,您将在应用程序崩溃时发现。不幸的是,追溯崩溃的根源可能很困难。
您可以在代码中使用 assert
和其他测试来创建断点,如果您正在调试或生成异常,如果它是 C++,这可能比仅仅崩溃提供更多信息。因此,在生成错误的源代码行之前添加这样的测试,在使用指针之前检查测试中的 NULL
可能会有所帮助。
或者如果该函数有一个状态代码指示它是否工作以及任何错误以及返回错误状态的某种方式,那么最有效的方法是在可能未初始化的指针处使用该错误报告如果完整性检查失败,则会生成指针错误。
但是,如果您能辨别出一个安全的默认值,您可能想改用它。辨别安全值需要查看源代码以确定安全默认值应该是多少。有时这样的安全值可以是初始化为零的适当类型变量的地址。
警告:如果返回指针中的地址,请勿使用函数局部变量的地址。当函数 returns 该地址将不再有效导致未定义行为时。
警告 2: 如果指针中的地址预计已使用 malloc()
或 new
或类似的内存分配器分配,则必须使用相同的机制,因此当某些代码决定使用 free()
或 delete
释放内存时,它将起作用。
如果指针的值局限于函数本身,则本次审查将需要阅读使用未初始化指针的函数的源代码。如果函数返回指针,函数导出的值给函数的用户,那么您还需要查看使用该函数的源代码以确定合适的默认值。
所以我建议你做的是,在你进行初始化的每个地方,你添加一个唯一的标识注释(类似于 "Inhahe fix uninitialized pointer error 06/10/2020" 的内容)到行中,这样你就可以进行搜索稍后找到这些,然后返回到有问题的代码中,并通过重构或更改代码以消除可能的未初始化指针错误来实际修复编译器错误。
在你做任何事情之前,先把源代码置于某种版本控制之下。
尽管如果 X64 构建可以 link 与旧的 32 位 VS6.0 构建一起使用会很棒,但我认为这将是一条艰难的道路。
我相信最大的希望是获取您拥有的 WinXP 代码并将其重新定位到 VS2019。在过去的几年里,我不得不经常这样做。
有一个一次性升级路径,您刚刚在 VS6.0 工作区中阅读它并构建了一组新的项目文件和 SLN 文件。
我对此的阅读使我相信 VS6->VSnewer 是在 VS2008 时间框架内完成的,'C++' 和 MSBUILD 环境中有一些“重大变化”,但是您可以生存下来并获得可构建的代码,只需稍作更改。
我发现的一个问题是自定义构建步骤。任何带有路径的自定义构建步骤都需要目录的尾部斜杠,并且任何带有引号的自定义构建步骤都可能被破坏,导致您的构建挂在 VS2013/VS2019 中。 (我在这方面的工作是 VS2013)。
代码的主要问题可能是 for 循环旧的 MS 编译器允许在 for 循环中声明的变量范围在预期范围之外持续存在。有一个编译器开关可以解决这个问题。
我记得 Platform Toolset V142 不支持 XP 系统,如果你需要针对 Win32 OS,那么你必须对那些二进制文件使用 V141_xp,否则源代码应该构建使用最新的平台工具集 V142 作为现代 windows 的 x64 构建很好。我已经成功地将大量 VS6.0 用户程序迁移到 VS2013 和现在的 VS2019,几乎没有问题。
有一个 WIN32 #define 可以保留它,因为它是遗留的并且不会破坏 x64 构建。
此外,在 VS6.0 中,“字符串池”存在一个罕见的编译器错误,其中生成的程序集将优化掉 2 个不同的字符串,就好像它们是相同的一样。字符串池与“Program Database For Execute And Continue”一起打开这会在幕后触发字符串池选项。所以我总是将其更改为“程序数据库”,因为我从未见过针对此的错误修复,并且怀疑它可能仍在代码中。这个 bug 够讨厌也够难,以至于多年后我仍然不敢开枪。
Google C 中的重大更改。但通常情况下,现代编译器会强制执行 1998 年甚至未定义的内容。我现在在编译时发现了 许多 错误在 VS6.0 中是 skipped/unnoticed。
我会一次拿一个 CPP 模块,查看第一个错误然后走下去。那么您正在使用的这个漂亮的库将获得新的生命。
我在 Visual Studio 6(在 Windows XP 下)中将 VolPack (https://graphics.stanford.edu/software/volpack/) 编译为静态库,因为我认为这就是它的目的,它不会' t 在 Visual Studio 2019 下编译。但是尝试在 Visual Studio 2019 和 link 到 volpack.lib 中编写 C++ 程序我得到错误:错误 LNK1104 无法打开文件 'LIBCD.lib'
(我不认为这是 VolPack 特有的错误,我认为它适用于在 VC 6 下编译的任何库,然后 linked 到更高版本的 VS,所以我认为这个问题对于 Whosebug 来说并不太具体。)
我发现了这个:https://support.microsoft.com/en-us/help/154753/description-of-the-default-c-and-c-libraries-that-a-program-will-link,这解释了为什么它使用该库,但我不知道在 VS 6 中如何处理它。我没有看到关于多线程的选项更改为让它使用不同的库,快速 Google 搜索显示 VS 6 不支持多线程。
我确实找到了这个:How to solve "cannot open file 'LIBCD.lib' " in visual studio 2008?,但我不确定该解决方案是否与我的问题相关,因为字符串 "GLUI" 在我尝试 [=39 的库中没有出现=] 到。即使它是我的问题的解决方案,我也不知道从哪里获得 GLUI 的源代码,我到底需要对 makefile 进行哪些更改,或者如何使 VS 6 使用新的重新编译的 GLUI,无论如何.
下一个解决方案基本上是告诉 linker 忽略 LIBCD.lib,但这给了我其他错误。我发现了这个:https://www.youtube.com/watch?v=zKrggjsgQx4,它基本上是说要忽略 LIBCD.lib,然后将运行时库更改为多线程调试,但这也给了我错误。
我尝试在 VS 2019 下编译 VolPack 时遇到的错误都是 "potentially unitialized local pointer variable",因此可能需要一些简单的修改才能使其在 VS 2019 下编译,但我不是 C 和我不想处理试图弄清楚如何修改程序和可能破坏程序的头痛。所以任何人都知道解决该问题的简单方法也可能有效。谢谢。
当您使用依赖于其他库的静态库时,如果编译器找不到那些其他库,它就会报错。
Microsoft Visual Studio 6.x 和 Visual Studio 2019 之间的差异是巨大的。由于我已经将旧代码(C 和 C++)从 6.x 移植到 VS 2015,因此由于 Microsoft 在遵守标准方面的改进,我不得不对源代码进行一些更改以允许编译工作以及支持新版本的标准,其中一些标准弃用了以前支持的结构。
查看此 post 关于版本之间的兼容性,Library ABI compatibility between versions of Visual Studio 另见:
ABI-Compatibility of visual studio c-libraries
而这张 blog posting from Microsoft about the release of Visual Studio 2019 日期为 2019 年的文章说:
Visual Studio 2019 version 16.0 is now available and is binary compatible with VS 2015/2017. In this first release of VS 2019, we’ve implemented more compiler and library features from the C++20 Working Paper, implemented more overloads (C++17’s “final boss”), and fixed many correctness, performance, and throughput issues. Here’s a list of the C++17/20 compiler/library feature work and the library fixes. (As usual, many compiler bugs were also fixed, but they aren’t listed here; compiler fixes tend to be specific to certain arcane code patterns. We recently blogged about compiler optimization and build throughput improvements in VS 2019, and we maintain a documentation page about compiler conformance improvements in VS 2019.)
除了使用源代码使其与 Visual Studio 2019 兼容之外,我没有看到任何其他资源。如果你看,你可能会发现你对 C 的专业水平足以实现以下是一些建议。
最好的做法似乎是对库进行必要的源代码更改,以便它可以在 Visual Studio 2019 下正确编译。
最好的做法是在每个发现未初始化指针错误的地方检查源代码并更正源代码,以便不再产生错误。以前在这些代码区域工作的程序员显然遗漏了潜在的控制流,这可能是因为他们期望根据函数的使用方式假设永远不会执行丢失的代码。很可能任何此类功能都很复杂,可能需要重构。
我经常看到这种类型的缺失流是由于 switch
语句缺少 default:
来捕获 switch
变量不是指定变量之一的事件案例值。也可能是由于 if
语句是一系列 else if
而没有最终的 else
来捕获任何其他可能的条件。或者它也可能是由于循环在初始化指针变量之前有一个 break
语句或者使用 continue
语句跳过变量初始化的地方。
在大多数情况下,这些问题是由于低内聚的函数 and/or 过于复杂和庞大,随着时间的推移引入此类问题的维护操作。
对于可能未初始化的指针的错误,一个不太理想的做法是只用一些适当的值进行初始化。可以跳转到错误的地方,点击变量然后到它定义的地方,然后给它设置一个合适的值。在大多数情况下,指针的值 NULL
是最安全的,因为如果它保持 NULL
并且在未修改为正确值的情况下使用,您的应用程序应该崩溃,让您知道存在问题。
通过初始化为 NULL
,您假设以前的程序员知道他们在做什么,并且编译器检测到的可能的流程将永远不会发生将变量保持不变为正确值的情况,因为逻辑。
如果发生未初始化的指针流,您将在应用程序崩溃时发现。不幸的是,追溯崩溃的根源可能很困难。
您可以在代码中使用 assert
和其他测试来创建断点,如果您正在调试或生成异常,如果它是 C++,这可能比仅仅崩溃提供更多信息。因此,在生成错误的源代码行之前添加这样的测试,在使用指针之前检查测试中的 NULL
可能会有所帮助。
或者如果该函数有一个状态代码指示它是否工作以及任何错误以及返回错误状态的某种方式,那么最有效的方法是在可能未初始化的指针处使用该错误报告如果完整性检查失败,则会生成指针错误。
但是,如果您能辨别出一个安全的默认值,您可能想改用它。辨别安全值需要查看源代码以确定安全默认值应该是多少。有时这样的安全值可以是初始化为零的适当类型变量的地址。
警告:如果返回指针中的地址,请勿使用函数局部变量的地址。当函数 returns 该地址将不再有效导致未定义行为时。
警告 2: 如果指针中的地址预计已使用 malloc()
或 new
或类似的内存分配器分配,则必须使用相同的机制,因此当某些代码决定使用 free()
或 delete
释放内存时,它将起作用。
如果指针的值局限于函数本身,则本次审查将需要阅读使用未初始化指针的函数的源代码。如果函数返回指针,函数导出的值给函数的用户,那么您还需要查看使用该函数的源代码以确定合适的默认值。
所以我建议你做的是,在你进行初始化的每个地方,你添加一个唯一的标识注释(类似于 "Inhahe fix uninitialized pointer error 06/10/2020" 的内容)到行中,这样你就可以进行搜索稍后找到这些,然后返回到有问题的代码中,并通过重构或更改代码以消除可能的未初始化指针错误来实际修复编译器错误。
在你做任何事情之前,先把源代码置于某种版本控制之下。
尽管如果 X64 构建可以 link 与旧的 32 位 VS6.0 构建一起使用会很棒,但我认为这将是一条艰难的道路。
我相信最大的希望是获取您拥有的 WinXP 代码并将其重新定位到 VS2019。在过去的几年里,我不得不经常这样做。
有一个一次性升级路径,您刚刚在 VS6.0 工作区中阅读它并构建了一组新的项目文件和 SLN 文件。
我对此的阅读使我相信 VS6->VSnewer 是在 VS2008 时间框架内完成的,'C++' 和 MSBUILD 环境中有一些“重大变化”,但是您可以生存下来并获得可构建的代码,只需稍作更改。
我发现的一个问题是自定义构建步骤。任何带有路径的自定义构建步骤都需要目录的尾部斜杠,并且任何带有引号的自定义构建步骤都可能被破坏,导致您的构建挂在 VS2013/VS2019 中。 (我在这方面的工作是 VS2013)。 代码的主要问题可能是 for 循环旧的 MS 编译器允许在 for 循环中声明的变量范围在预期范围之外持续存在。有一个编译器开关可以解决这个问题。
我记得 Platform Toolset V142 不支持 XP 系统,如果你需要针对 Win32 OS,那么你必须对那些二进制文件使用 V141_xp,否则源代码应该构建使用最新的平台工具集 V142 作为现代 windows 的 x64 构建很好。我已经成功地将大量 VS6.0 用户程序迁移到 VS2013 和现在的 VS2019,几乎没有问题。
有一个 WIN32 #define 可以保留它,因为它是遗留的并且不会破坏 x64 构建。
此外,在 VS6.0 中,“字符串池”存在一个罕见的编译器错误,其中生成的程序集将优化掉 2 个不同的字符串,就好像它们是相同的一样。字符串池与“Program Database For Execute And Continue”一起打开这会在幕后触发字符串池选项。所以我总是将其更改为“程序数据库”,因为我从未见过针对此的错误修复,并且怀疑它可能仍在代码中。这个 bug 够讨厌也够难,以至于多年后我仍然不敢开枪。
Google C 中的重大更改。但通常情况下,现代编译器会强制执行 1998 年甚至未定义的内容。我现在在编译时发现了 许多 错误在 VS6.0 中是 skipped/unnoticed。
我会一次拿一个 CPP 模块,查看第一个错误然后走下去。那么您正在使用的这个漂亮的库将获得新的生命。