【问题标题】:What does it mean to [not] have vsnprintf, _vsnprintf[没有] 有 vsnprintf, _vsnprintf 是什么意思
【发布时间】:2020-04-09 07:44:53
【问题描述】:

我应该在项目中的所有config.h 文件中使用相同的设置吗?

症状:nmake 尝试在 MSVC 的“命令提示符”中构建项目的一部分时抛出 inconsistent dll linkage vsnprintf。谷歌搜索该消息说这通常与宏无法始终如一地工作有关。我正在构建一个可能有效的软件包;我没有更改发行版。

这两个 Microsoft 例程记录在 hereconfig.h 文件中有标记

/* Define to 1 if you have the `vsnprintf' function. */
/* #undef HAVE_VSNPRINTF */
...
/* Define to 1 if you have the `_vsnprintf' function. */
#define HAVE__VSNPRINTF 1

部分但不是全部config.h 文件是在安装包时从config.h.in/configure.ac 生成的。我似乎在项目的不同子树中的不同config.hs 中对HAVE_VSNPRINTF 有不同的设置。我不想覆盖发行版,但这似乎不对(?)

vsnprintfMSVCRnnn.DLL 中,其中nnn 是MSVC 版本;我已经安装了 v12.0/Update 5 社区。为什么会有这么旧的版本? ...

背景

我正在尝试构建一个古老版本的 Haskell Hugs 编译器,2006 年 9 月。这主要是为 C/C++ 中的 Unix 环境编写的。但我是在基于 x64 的 Windows 8.1 处理器上构建的。我遵循的说明是here;并且该 repo 包含我正在构建的整个目录结构(谢谢 Franklin Chen)。

我构建的面向 Unix 的部分,使用 MinGW/MSYS,而不是 Cygwin。 (64位的MinGW不太好,所以回退了用32位的。)

现在我正在尝试构建 Windows 部分,它本质上是 Unix 上的 GUI 单板——从说明中的“使用 Microsoft Visual C++”开始。 Visual Studio 一点也不高兴:项目文件是.vcproj,不再受支持。我尝试devenv /Upgrade 将它们设为.vcxproj。但随后尝试MSBuild 时出现更多问题,它无法针对.xsd 进行验证; Microsoft.Build.{Core|Common}.xsd 中的任何一个都拒绝了很多关于缺少类型的内容。所以我放弃了这种方法。

所以我按照说明“从命令行驱动 Microsoft Visual C++”,使用 MSVC 提供的 .bat 文件启动命令行 as doco'd herenmake 正在运行,但会抛出大量 inconsistent dll 警告,仅限 vsnprintf。我还收到了differs in parameter lists 的各种例程;这是一个连锁错误吗?最终nmake 崩溃了,没有构建我想要的.exes。

【问题讨论】:

  • 我强烈推荐使用 MSYS2 而不是 MSYS ,它更好。您可以安装 32 位或 64 位构建和目标。
  • 我首先尝试了MSYS2;由于 MSYS2 定义的环境变量 Hugs 在 2006 年没有听说过,因此构建例程一直在抱怨。(这就是我恢复为 32 位的原因。)我机器的 Unix 环境仅用于构建这个应用程序。
  • MSYS2 有 32 位和 64 位版本。如果您使用的是 MSYS2 32 位,则没有“恢复为 32 位”。

标签: c++ msvcrt


【解决方案1】:

配置脚本的想法是确定你的编译器是否有vsnprintf。当然,各种生成的config.h 文件会得到不同的结果,这就是重点。如果都是vsprintf,就不用查了!

话虽如此,我还是将configure.ac 机制描述为非常古老。不止一次,我发现从头开始创建一个新的.vcxproj 会更容易。

我不确定您链接的 MSDN 文档。您链接到 VC14.x 文档,该文档指出 vsnprintf 自您声称使用的 VC12.0 以来已更改。

【讨论】:

  • 谢谢,但很抱歉我不明白:我的编译器还是我的机器?如果vsnprintfmachine 上,不是所有编译器都使用它吗?特别是如果他们正在构建一个应用程序。我假设config.h 是为了应对在不同机器上的编译。无论如何:有效的makeHAVE_VSNPRINTF 1;不起作用的nmake 没有定义HAVE_VSNPRINTF
  • 我链接了 2019 年的文档,因为这就是 Microsoft 网站上提供的所有内容。感谢关于版本更改的提示,就像我安装了 VC12.0。
  • @AntC:vsnprintf 是通用 CRT 的一部分,它在每台 Windows 10 机器上,但您特别提到使用 Windows 8.1。 “在每台机器上编译”逻辑对于 Unix 来说是典型的,但在 Windows 上却闻所未闻。绝大多数 Windows PC 甚至都没有安装编译器。这就是您拥有 Visual C++ 可再发行库的原因,并且该安装程序还负责 Win8.1 上的通用 CRT
  • 顺便说一句,.vcproj 是发行版附带的(2005 年发布的),configure.ac 没有碰过它。
  • @AntC 您用于编译项目的编译器。截至目前,我有 3 个不同版本的 MSVC,它们是同一台机器上的库,因为我从事的项目不会同时升级工具
【解决方案2】:

我已经为这个特定的应用程序解决了这个问题。 #define HAVE_VSNPRINTF 1#define HAVE_SNPRINTF 1 中的 config.h 使 inconsistent dll linkage vsnprintf 错误消失。也就是说,我将这些标志更改为与configure.ac-生成的config.h 中的相同。

在项目中,不同的子树中有许多config.h 设置了这些标志。但是只有一个文件可以读取它/对其执行操作:src/machdep.c“机器相关代码”。这是所有应用程序的#included。这个应用程序本质上是为 Unix 平台编写的,我期望机器范围的设置。

我在@MSalters 的回答中指出,MSVC 平台不一定期望在机器范围内具有相同的设置。但是这个应用程序与 Unix/MSys 和 MSVC 环境有着紧密的联系,所以我希望他们需要一致性。

那我就进步了。我还没有编译整个应用程序:它更进一步,所以我对其他例程有更多inconsistent dll linkage ... 错误。我可以在config.hs 中看到标志设置的进一步不一致。

【讨论】:

    【解决方案3】:

    另一种答案:

    C4273: 'xxx' inconsistent dll linkage 的症状是警告而不是错误,因此编译器会继续。 vsnprintf 和朋友将参数列表格式化为输出缓冲区。因此,项目中不同的.exes 是否链接到不同的版本可能并不重要。在最坏的情况下,对于相同的参数,它们会在输出中产生不同的结果。

    所以请忽略该消息,不要担心config.h 中的差异。

    完全披露:在编辑config.h 以使vsnprintf 等消息消失后​​;我对mallocfree 有一些残留的不一致之处——尽管编辑了config.h 以获取与ALLOC 相关的任何设置。不同.exes 之间的分配行为差异更令人担忧。

    【讨论】:

      猜你喜欢
      • 2012-08-18
      • 1970-01-01
      • 2023-04-06
      • 2015-08-16
      • 2018-10-30
      • 1970-01-01
      • 1970-01-01
      • 2022-10-04
      • 2010-10-14
      相关资源
      最近更新 更多