【问题标题】:Qt-Based C++ Project Works If Run From cmd.exe But Not From Within Qt Creator如果从 cmd.exe 但不能从 Qt Creator 中运行,则基于 Qt 的 C++ 项目可以工作
【发布时间】:2020-08-12 00:55:13
【问题描述】:

我正在为 Windows 编写一个非常小的基于 C/C++ Qt 的应用程序(仅限 Windows——根本不是跨平台),它使用 VISA 库 (visa64.dll) 与一些外部硬件通信。反过来,该库使用其他一些库:

(来自 Dependency Walker 又名dependency.exe 的屏幕截图)

最初我是在 Visual Studio 中编写的,效果很好。然后我将它移植到 Qt Creator(使用 Qt5,w/MSVC 2015 Visual C++ 工具链),我得到了运行时错误。它知道在哪里可以找到外部头文件,所以我认为我的 INCLUDEPATH 是正确的,并且它构建得很好,所以我认为我的 .pro 文件中的 LIBS 变量是正确的,也就是说它可以找到它需要的 .lib 文件。但是,我从这个外部库 (viOpenDefaultRM) 调用的第一个 API 返回以下错误:VI_ERROR_LIBRARY_NFOUND。无论我是进行调试构建还是发布构建,以及是否使用调试器运行它,都会发生这种情况。只要我从 Qt Creator 中运行程序,它就会出现运行时错误。

这是我的 .pro 文件:

TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt

SOURCES += main.cpp

INCLUDEPATH += $$PWD/'../../../../Program Files/IVI Foundation/VISA/Win64/Include'

LIBS += -L$$PWD/'../../../../Program Files/IVI Foundation/VISA/Win64/Lib_x64/msc/' -lvisa64

INCLUDEPATH += $$PWD/'../../../../Program Files/IVI Foundation/VISA/Win64/Include'
DEPENDPATH += $$PWD/'../../../../Program Files/IVI Foundation/VISA/Win64/Include'

/Include 结尾的路径有头文件(.h)(它是一个C 库),以/msc 结尾的路径有一个.lib 文件。 .lib 文件不是静态库,它们是一些相应 DLL 的接口文件。这些 DLL 文件位于 C:\System32 中。 C:\SysWOW64 中也有 32 位版本。它们也可能存在于其他地方,但如果它们存在,我不知道。

现在,如果我从 cmd.exe 运行它,它工作正常。也就是说,如果我打开一个 cmd.exe 终端窗口并导航到我的 Qt 项目的构建目录 (c:\blah\blah\blah\obj\debug\) 并从 cmd.exe 运行可执行文件,我不会收到运行时错误。它可以连接到外部硬件,与它交谈,所有美好的事情都在发生,非常高兴。

我已经对这个问题进行了大量的搜索和研究,但我有点被大多数人遇到相反问题的事实所诅咒,这意味着 那个 问题(相反的一个我的)是在 Google/DuckDuckGo/StackOverflow/forum.qt.io/doc.qt.io 搜索中出现的内容。该问题通常与丢失/放错的 Qt 库有关。 Here 就是一个例子。这个问题的答案通常以一个链接结束,该链接指向如何为 Windows 部署 Qt 项目的页面,例如this article.

我还阅读了来自 Qt 的 this 关于如何将库添加到您的项目的文章,但它并没有帮助我,但我可能遗漏了一些东西和/或做错了。

这可能是我想念的一些非常愚蠢的东西,坦率地说我希望它是。谢谢*10^6。

【问题讨论】:

  • 您是否尝试静态链接?我想是的,因为这是一个.lib。您是否尝试过指定库的扩展名(例如 visa64.lib)?究竟是什么产生了这个 VI_ERROR_LIBRARY_NFOUND 错误?因为根据您的链接方式,您应该会在运行时看到一个编译时错误,指出库丢失、找不到文件或未定义符号。顺便说一句,您已将两次 INCLUDEPATH 添加到 VISA,但这并不重要。
  • 我正在尝试动态链接,尽管我可能会对其进行比较。但是 .lib 文件只是 system32 中相应 DLL 中的所有符号。我认为 .lib 文件就像在这种情况下为 visa64.dll 调用了一堆 LoadLibraryA() ,但库的编译代码在 visa64.dll 中。如果我理解正确。所以我相信 .lib 文件必须存在才能编译项目,但在运行时 DLL 是 API 的实际编译代码所在的位置。 VI_ERROR_LIBRARY_NFOUND 表示通常无法找到或加载 VISA 或 VISA 需要的库。
  • 对,不要再那么频繁地做 Windows 开发了!所以我所说的“什么是产生错误VI_...”的意思是我很惊讶它会这样显示,除非有东西在运行时寻找它并链接到它,就像插件一样。这意味着您首先甚至不需要-lvisa64。会不会是 viopenDefaultRM() 失败,因为正确的插件/文件不在其查找的路径中?在这里,您尝试使用 -l 在链接器中将其注册为依赖库,但在我看来,应用程序启动正常,然后它尝试加载 visa64 并失败
  • ... 我会假设 viopenDefaultRM() 在特定位置寻找它,只是没有找到它
  • 我认为你是对的,viOpenDefaultRM() 失败 b/c 它找不到正确的插件/文件,也许是 DLL,它正在寻找的地方。我认为。我认为即使在我的代码中调用viOpenDefaultRM(),它也可以编译的原因是因为-lvisa64 标志是指visa64.lib。 visa64.lib 我认为它提供了来自其他地方的 DLL (visa64.dll) 的 API 名称。所以我猜它要么因为某种原因不知道在哪里可以找到 visa64.dll,要么它在错误的地方寻找我不知道的不同版本的 visa64.dll。

标签: c++ windows visual-c++ qt-creator visa


【解决方案1】:

TL;DR: 我用于在 Qt Creator 中编译的套件与我的系统 PATH 设置不同的 PATH。为了解决这个问题,我在cmd.exe 中执行了echo %PATH 并将所有与我尝试使用的驱动程序有关的内容复制到PATH 中,用于我在Qt Creator 中使用的套件。更多详情如下。

我今天早上开始工作了。正如@adrien-lerevat 所建议的,当从 Qt Creator 中运行时,我的可执行文件找不到它需要的一些 DLL。总而言之,我在我的工具包中定义了一个PATH(Qt 中的“工具包”基本上是一个编译器、一个调试器和一些环境变量),它不同于,不是 em> 一个超集,我的正常系统路径。你看,我从其他项目继承了这个套件用于其他目的,我没有意识到可以在其中设置PATH,或者我正在设置一个。所以要找到我为 Qt Creator 设置的PATH,我去了Tools 下拉菜单并选择了Options...,然后是Build & Run,然后是Kits。然后单击您正在使用的工具包进行编辑。像这样:

这应该会给你一个东西列表,其中一个东西叫做Environment。那应该有一个Change... 按钮,你可以按下:

这应该会打开一个包含所有环境内容的新窗口:

(截图来自之后我解决了问题)

这是我找到PATH 的地方,以及一些值得了解的库和包含路径。所以现在我知道我的 Qt Creator PATH 是什么,我打开 cmd.exe 并输入命令 echo %PATH% 来找出我的系统 PATH 是什么。我抓取了与我正在使用的这些 VISA 驱动程序有关的所有内容(基本上是路径中带有VISA 和/或IVI Foundation 的任何内容)并将它们粘贴到我在Qt Creator 中的PATH 中。这是我粘贴在其中以使其正常工作的内容列表:

C:\WINDOWS\system32;C:\Program Files\IVI Foundation\VISA\Win64\ktvisa;C:\Program Files\IVI Foundation\VISA\Win64\bin;C:\Program Files (x86)\IVI Foundation\VISA\WinNT\bin;C:\Program Files (x86)\IVI Foundation\VISA\WinNT\Bin\;C:\Program Files\IVI Foundation\VISA\Win64\Bin\;C:\Program Files (x86)\IVI Foundation\VISA\winnt\agvisa;C:\Program Files\Keysight\IO Libraries Suite\bin;C:\Program Files (x86)\Keysight\IO Libraries Suite\bin;C:\Program Files (x86)\IVI Foundation\VISA\WinNT\ktvisa;C:\Program Files (x86)\IVI Foundation\IVI\bin;C:\Program Files\IVI Foundation\IVI\bin;

我添加了c:\system32,因为我知道visa64.dll 所在的位置,它至少是一个我知道我需要的顶级DLL。不过,奇怪的是,当我添加 just c:\system32 而没有所有 VISAIVI Foundation 的东西时,这不起作用。所以,我不知道我添加到我的 Qt Creator 路径中的 所有内容 是否是必要的,因为我刚刚遇到了这个解决方案,但是一旦我削减了列表以找出我实际的所有内容需要我将在此处添加该信息。以防万一其他人遇到这个问题或好奇。为了完整起见,我想。好的,谢谢大家;)

【讨论】:

    猜你喜欢
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    相关资源
    最近更新 更多